home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_emacs.idb / usr / freeware / share / emacs / 19.34 / lisp / cc-mode.el.z / cc-mode.el
Encoding:
Text File  |  1998-10-28  |  179.0 KB  |  5,031 lines

  1. ;;; cc-mode.el --- major mode for editing C, C++, and Objective-C code
  2.  
  3. ;; Copyright (C) 1985, 87, 92, 93, 94, 95, 96 Free Software Foundation, Inc.
  4.  
  5. ;; Authors: 1992-1996 Barry A. Warsaw
  6. ;;          1987 Dave Detlefs and Stewart Clamen
  7. ;;          1985 Richard M. Stallman
  8. ;; Created: a long, long, time ago. adapted from the original c-mode.el
  9. ;; Barry Warsaw Version:    4.282
  10. ;; Keywords: c languages oop
  11.  
  12. ;; NOTE: Read the commentary below for the right way to submit bug reports!
  13. ;; NOTE: See the accompanying texinfo manual for details on using this mode!
  14.  
  15. ;; This file is part of GNU Emacs.
  16.  
  17. ;; GNU Emacs is free software; you can redistribute it and/or modify
  18. ;; it under the terms of the GNU General Public License as published by
  19. ;; the Free Software Foundation; either version 2, or (at your option)
  20. ;; any later version.
  21.  
  22. ;; GNU Emacs is distributed in the hope that it will be useful,
  23. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  25. ;; GNU General Public License for more details.
  26.  
  27. ;; You should have received a copy of the GNU General Public License
  28. ;; along with GNU Emacs; see the file COPYING.  If not, write to the
  29. ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  30. ;; Boston, MA 02111-1307, USA.
  31.  
  32. ;;; Commentary:
  33.  
  34. ;;;    This file may contain modifications made by the FSF for inclusion
  35. ;;;    in the Emacs release.  It may not be identical to the version
  36. ;;;    written by Barry Warsaw, so bugs are not necessarily his fault.
  37. ;;;    However, these changes are usually small, so we still do recommend
  38. ;;;    reporting bugs to him with C-c C-b.  Even when they are not his fault,
  39. ;;;    he may fix them for the FSF's sake.
  40.  
  41. ;; This package provides modes in GNU Emacs for editing C, C++, 
  42. ;; Objective-C, and Java code. It is intended to be a replacement for
  43. ;; c-mode.el (a.k.a. BOCM -- Boring Old C-Mode), and c++-mode.el
  44. ;; (a.k.a cplus-md.el and cplus-md1.el), both of which are ancestors
  45. ;; of this file.  A number of important improvements have been made,
  46. ;; briefly: complete K&R C, ANSI C, `ARM' C++, Objective-C, and Java
  47. ;; support with consistent indentation across all modes, more
  48. ;; intuitive indentation controlling variables, compatibility across
  49. ;; all known Emacsen, nice new features, and tons of bug fixes.  This
  50. ;; package is called "cc-mode" to distinguish it from its ancestors,
  51. ;; but there really is no top-level cc-mode.  Usage and programming
  52. ;; details are contained in an accompanying texinfo manual.
  53.  
  54. ;; To submit bug reports, type "C-c C-b".  These will be sent to
  55. ;; bug-gnu-emacs@prep.ai.mit.edu and I'll read about them there (this
  56. ;; is mirrored as the Usenet newsgroup gnu.emacs.bug).  Questions can
  57. ;; sent to help-gnu-emacs@prep.ai.mit.edu (mirrored as
  58. ;; gnu.emacs.help).  Please do not send bugs or questions to my
  59. ;; personal account.
  60.  
  61. ;; YOU CAN IGNORE ALL BYTE-COMPILER WARNINGS. They are the result of
  62. ;; the multi-Emacsen support.  Emacs 19 (from the FSF), XEmacs 19
  63. ;; (formerly Lucid Emacs), and GNU Emacs 18 all do things differently
  64. ;; and there's no way to shut the byte-compiler up at the necessary
  65. ;; granularity.  Let me say this again: YOU CAN IGNORE ALL
  66. ;; BYTE-COMPILER WARNINGS (you'd be surprised at how many people don't
  67. ;; follow this advice :-).
  68.  
  69. ;; If your Emacs is dumped with c-mode.el and/or c++-mode.el, you will
  70. ;; need to add the following to your .emacs file before any other
  71. ;; reference to c-mode or c++-mode:
  72. ;;
  73. ;; (fmakunbound 'c-mode)
  74. ;; (makunbound 'c-mode-map)
  75. ;; (fmakunbound 'c++-mode)
  76. ;; (makunbound 'c++-mode-map)
  77. ;; (makunbound 'c-style-alist)
  78.  
  79. ;; If your Emacs comes with cc-mode already (and as of 18-Jan-1996,
  80. ;; XEmacs 19.13 and Emacs 19.30 both do), you only need to add the
  81. ;; following to use the latest version of cc-mode:
  82. ;;
  83. ;; (load "cc-mode")
  84. ;;
  85. ;; Make sure the new version is earlier on your load-path.
  86.  
  87. ;; There are four major mode entry points provided by this package,
  88. ;; one for editing C++ code, one for editing C code (both K&R and
  89. ;; ANSI), one for editing Objective-C code, and one for editing Java
  90. ;; code.  The commands are M-x c-mode, M-x c++-mode, M-x objc-mode,
  91. ;; and M-x java-mode.
  92.  
  93. ;; If you are using an old version of Emacs which does not come
  94. ;; with cc-mode.el, you will need to do these things
  95. ;; to use it:
  96. ;;
  97. ;; (autoload 'c++-mode  "cc-mode" "C++ Editing Mode" t)
  98. ;; (autoload 'c-mode    "cc-mode" "C Editing Mode" t)
  99. ;; (autoload 'objc-mode "cc-mode" "Objective-C Editing Mode" t)
  100. ;; (autoload 'java-mode "cc-mode" "Java Editing Mode" t)
  101. ;; (setq auto-mode-alist
  102. ;;   (append '(("\\.C$"    . c++-mode)
  103. ;;             ("\\.cc$"   . c++-mode)
  104. ;;             ("\\.c$"    . c-mode)
  105. ;;             ("\\.h$"    . c-mode)
  106. ;;             ("\\.m$"    . objc-mode)
  107. ;;             ("\\.java$" . java-mode)
  108. ;;            ) auto-mode-alist))
  109. ;;
  110. ;; You do not need these changes in Emacs versions that come with cc-mode.
  111.  
  112. ;; Many, many thanks go out to all the folks on the beta test list.
  113. ;; Without their patience, testing, insight, code contributions, and
  114. ;; encouragement cc-mode.el would be a far inferior package.
  115.  
  116. ;; Anonymous ftp URL:
  117. ;;
  118. ;;    ftp://ftp.python.org/pub/emacs/cc-mode.tar.gz
  119.  
  120. ;;; Code:
  121.  
  122.  
  123. ;; user definable variables
  124. ;; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  125.  
  126. (defvar c-inhibit-startup-warnings-p nil
  127.   "*If non-nil, inhibits start up compatibility warnings.")
  128. (defvar c-strict-syntax-p nil
  129.   "*If non-nil, all syntactic symbols must be found in `c-offsets-alist'.
  130. If the syntactic symbol for a particular line does not match a symbol
  131. in the offsets alist, an error is generated, otherwise no error is
  132. reported and the syntactic symbol is ignored.")
  133. (defvar c-echo-syntactic-information-p nil
  134.   "*If non-nil, syntactic info is echoed when the line is indented.")
  135. (defvar c-basic-offset 4
  136.   "*Amount of basic offset used by + and - symbols in `c-offsets-alist'.")
  137.  
  138. (defvar c-offsets-alist
  139.   '((string                . -1000)
  140.     (c                     . c-lineup-C-comments)
  141.     (defun-open            . 0)
  142.     (defun-close           . 0)
  143.     (defun-block-intro     . +)
  144.     (class-open            . 0)
  145.     (class-close           . 0)
  146.     (inline-open           . +)
  147.     (inline-close          . 0)
  148.     (ansi-funcdecl-cont    . +)
  149.     (knr-argdecl-intro     . +)
  150.     (knr-argdecl           . 0)
  151.     (topmost-intro         . 0)
  152.     (topmost-intro-cont    . 0)
  153.     (member-init-intro     . +)
  154.     (member-init-cont      . 0)
  155.     (inher-intro           . +)
  156.     (inher-cont            . c-lineup-multi-inher)
  157.     (block-open            . 0)
  158.     (block-close           . 0)
  159.     (brace-list-open       . 0)
  160.     (brace-list-close      . 0)
  161.     (brace-list-intro      . +)
  162.     (brace-list-entry      . 0)
  163.     (statement             . 0)
  164.     ;; some people might prefer
  165.     ;;(statement             . c-lineup-runin-statements)
  166.     (statement-cont        . +)
  167.     ;; some people might prefer
  168.     ;;(statement-cont        . c-lineup-math)
  169.     (statement-block-intro . +)
  170.     (statement-case-intro  . +)
  171.     (statement-case-open   . 0)
  172.     (substatement          . +)
  173.     (substatement-open     . +)
  174.     (case-label            . 0)
  175.     (access-label          . -)
  176.     (label                 . 2)
  177.     (do-while-closure      . 0)
  178.     (else-clause           . 0)
  179.     (comment-intro         . c-lineup-comment)
  180.     (arglist-intro         . +)
  181.     (arglist-cont          . 0)
  182.     (arglist-cont-nonempty . c-lineup-arglist)
  183.     (arglist-close         . +)
  184.     (stream-op             . c-lineup-streamop)
  185.     (inclass               . +)
  186.     (cpp-macro             . -1000)
  187.     (friend                . 0)
  188.     (objc-method-intro     . -1000)
  189.     (objc-method-args-cont . c-lineup-ObjC-method-args)
  190.     (objc-method-call-cont . c-lineup-ObjC-method-call)
  191.     )
  192.   "*Association list of syntactic element symbols and indentation offsets.
  193. As described below, each cons cell in this list has the form:
  194.  
  195.     (SYNTACTIC-SYMBOL . OFFSET)
  196.  
  197. When a line is indented, cc-mode first determines the syntactic
  198. context of the line by generating a list of symbols called syntactic
  199. elements.  This list can contain more than one syntactic element and
  200. the global variable `c-syntactic-context' contains the context list
  201. for the line being indented.  Each element in this list is actually a
  202. cons cell of the syntactic symbol and a buffer position.  This buffer
  203. position is called the relative indent point for the line.  Some
  204. syntactic symbols may not have a relative indent point associated with
  205. them.
  206.  
  207. After the syntactic context list for a line is generated, cc-mode
  208. calculates the absolute indentation for the line by looking at each
  209. syntactic element in the list.  First, it compares the syntactic
  210. element against the SYNTACTIC-SYMBOL's in `c-offsets-alist'.  When it
  211. finds a match, it adds the OFFSET to the column of the relative indent
  212. point.  The sum of this calculation for each element in the syntactic
  213. list is the absolute offset for line being indented.
  214.  
  215. If the syntactic element does not match any in the `c-offsets-alist',
  216. an error is generated if `c-strict-syntax-p' is non-nil, otherwise
  217. the element is ignored.
  218.  
  219. Actually, OFFSET can be an integer, a function, a variable, or one of
  220. the following symbols: `+', `-', `++', `--', `*', or `/'.  These
  221. latter designate positive or negative multiples of `c-basic-offset',
  222. respectively: *1, *-1, *2, *-2, *0.5, and *-0.5. If OFFSET is a
  223. function, it is called with a single argument containing the cons of
  224. the syntactic element symbol and the relative indent point.  The
  225. function should return an integer offset.
  226.  
  227. Here is the current list of valid syntactic element symbols:
  228.  
  229.  string                 -- inside multi-line string
  230.  c                      -- inside a multi-line C style block comment
  231.  defun-open             -- brace that opens a function definition
  232.  defun-close            -- brace that closes a function definition
  233.  defun-block-intro      -- the first line in a top-level defun
  234.  class-open             -- brace that opens a class definition
  235.  class-close            -- brace that closes a class definition
  236.  inline-open            -- brace that opens an in-class inline method
  237.  inline-close           -- brace that closes an in-class inline method
  238.  ansi-funcdecl-cont     -- the nether region between an ANSI function
  239.                            declaration and the defun opening brace
  240.  knr-argdecl-intro      -- first line of a K&R C argument declaration
  241.  knr-argdecl            -- subsequent lines in a K&R C argument declaration
  242.  topmost-intro          -- the first line in a topmost construct definition
  243.  topmost-intro-cont     -- topmost definition continuation lines
  244.  member-init-intro      -- first line in a member initialization list
  245.  member-init-cont       -- subsequent member initialization list lines
  246.  inher-intro            -- first line of a multiple inheritance list
  247.  inher-cont             -- subsequent multiple inheritance lines
  248.  block-open             -- statement block open brace
  249.  block-close            -- statement block close brace
  250.  brace-list-open        -- open brace of an enum or static array list
  251.  brace-list-close       -- close brace of an enum or static array list
  252.  brace-list-intro       -- first line in an enum or static array list
  253.  brace-list-entry       -- subsequent lines in an enum or static array list
  254.  statement              -- a C/C++/ObjC statement
  255.  statement-cont         -- a continuation of a C/C++/ObjC statement
  256.  statement-block-intro  -- the first line in a new statement block
  257.  statement-case-intro   -- the first line in a case `block'
  258.  statement-case-open    -- the first line in a case block starting with brace
  259.  substatement           -- the first line after an if/while/for/do/else
  260.  substatement-open      -- the brace that opens a substatement block
  261.  case-label             -- a case or default label
  262.  access-label           -- C++ private/protected/public access label
  263.  label                  -- any non-special C/C++/ObjC label
  264.  do-while-closure       -- the `while' that ends a do/while construct
  265.  else-clause            -- the `else' of an if/else construct
  266.  comment-intro          -- a line containing only a comment introduction
  267.  arglist-intro          -- the first line in an argument list
  268.  arglist-cont           -- subsequent argument list lines when no
  269.                            arguments follow on the same line as the
  270.                            the arglist opening paren
  271.  arglist-cont-nonempty  -- subsequent argument list lines when at
  272.                            least one argument follows on the same
  273.                            line as the arglist opening paren
  274.  arglist-close          -- the solo close paren of an argument list
  275.  stream-op              -- lines continuing a stream operator construct
  276.  inclass                -- the construct is nested inside a class definition
  277.  cpp-macro              -- the start of a cpp macro
  278.  friend                 -- a C++ friend declaration
  279.  objc-method-intro      -- the first line of an Objective-C method definition
  280.  objc-method-args-cont  -- lines continuing an Objective-C method definition
  281.  objc-method-call-cont  -- lines continuing an Objective-C method call
  282. ")
  283.  
  284. (defvar c-tab-always-indent t
  285.   "*Controls the operation of the TAB key.
  286. If t, hitting TAB always just indents the current line.  If nil,
  287. hitting TAB indents the current line if point is at the left margin or
  288. in the line's indentation, otherwise it insert a real tab character.
  289. If other than nil or t, then tab is inserted only within literals
  290. -- defined as comments and strings -- and inside preprocessor
  291. directives, but line is always reindented.
  292.  
  293. Note that indentation of lines containing only comments is also
  294. controlled by the `c-comment-only-line-offset' variable.")
  295.  
  296. (defvar c-comment-only-line-offset 0
  297.   "*Extra offset for line which contains only the start of a comment.
  298. Can contain an integer or a cons cell of the form:
  299.  
  300.  (NON-ANCHORED-OFFSET . ANCHORED-OFFSET)
  301.  
  302. Where NON-ANCHORED-OFFSET is the amount of offset given to
  303. non-column-zero anchored comment-only lines, and ANCHORED-OFFSET is
  304. the amount of offset to give column-zero anchored comment-only lines.
  305. Just an integer as value is equivalent to (<val> . -1000).")
  306.  
  307. (defvar c-indent-comments-syntactically-p nil
  308.   "*Specifies how comment-only lines should be indented.
  309. When this variable is non-nil, comment-only lines are indented
  310. according to syntactic analysis via `c-offsets-alist', even when
  311. \\[indent-for-comment] is used.")
  312.  
  313. (defvar c-block-comments-indent-p nil
  314.   "*Specifies how to re-indent C style block comments.
  315.  
  316. Examples of the supported styles of C block comment indentation are
  317. shown below.  When this variable is nil, block comments are indented
  318. as shown in styles 1 through 4.  If this variable is non-nil, block
  319. comments are indented as shown in style 5.
  320.  
  321. Note that cc-mode does not automatically insert any stars or block
  322. comment delimiters.  You must type these in manually.  This variable
  323. only controls how the lines within the block comment are indented when
  324. you hit ``\\[c-indent-command]''.
  325.  
  326.  style 1:    style 2 (GNU):    style 3:     style 4:     style 5:
  327.  /*          /* Blah           /*           /*           /*
  328.     blah        blah.  */       * blah      ** blah      blah
  329.     blah                        * blah      ** blah      blah
  330.     */                          */          */           */")
  331.  
  332. (defvar c-cleanup-list '(scope-operator)
  333.   "*List of various C/C++/ObjC constructs to \"clean up\".
  334. These clean ups only take place when the auto-newline feature is turned
  335. on, as evidenced by the `/a' or `/ah' appearing next to the mode name.
  336. Valid symbols are:
  337.  
  338.  brace-else-brace    -- cleans up `} else {' constructs by placing entire
  339.                         construct on a single line.  This clean up only
  340.                         takes place when there is nothing but white
  341.                         space between the braces and the `else'.  Clean
  342.             up occurs when the open-brace after the `else'
  343.             is typed.
  344.  empty-defun-braces  -- cleans up empty defun braces by placing the
  345.                         braces on the same line.  Clean up occurs when
  346.             the defun closing brace is typed.
  347.  defun-close-semi    -- cleans up the terminating semi-colon on defuns
  348.             by placing the semi-colon on the same line as
  349.             the closing brace.  Clean up occurs when the
  350.             semi-colon is typed.
  351.  list-close-comma    -- cleans up commas following braces in array
  352.                         and aggregate initializers.  Clean up occurs
  353.             when the comma is typed.
  354.  scope-operator      -- cleans up double colons which may designate
  355.             a C++ scope operator split across multiple
  356.             lines. Note that certain C++ constructs can
  357.             generate ambiguous situations.  This clean up
  358.             only takes place when there is nothing but
  359.             whitespace between colons. Clean up occurs
  360.             when the second colon is typed.")
  361.  
  362. (defvar c-hanging-braces-alist '((brace-list-open)
  363.                  (substatement-open after)
  364.                  (block-close . c-snug-do-while))
  365.   "*Controls the insertion of newlines before and after braces.
  366. This variable contains an association list with elements of the
  367. following form: (SYNTACTIC-SYMBOL . ACTION).
  368.  
  369. When a brace (either opening or closing) is inserted, the syntactic
  370. context it defines is looked up in this list, and if found, the
  371. associated ACTION is used to determine where newlines are inserted.
  372. If the context is not found, the default is to insert a newline both
  373. before and after the brace.
  374.  
  375. SYNTACTIC-SYMBOL can be any of: defun-open, defun-close, class-open,
  376. class-close, inline-open, inline-close, block-open, block-close,
  377. substatement-open, statement-case-open, brace-list-open,
  378. brace-list-close, brace-list-intro, or brace-list-entry. See
  379. `c-offsets-alist' for details.
  380.  
  381. ACTION can be either a function symbol or a list containing any
  382. combination of the symbols `before' or `after'.  If the list is empty,
  383. no newlines are inserted either before or after the brace.
  384.  
  385. When ACTION is a function symbol, the function is called with a two
  386. arguments: the syntactic symbol for the brace and the buffer position
  387. at which the brace was inserted.  The function must return a list as
  388. described in the preceding paragraph.  Note that during the call to
  389. the function, the variable `c-syntactic-context' is set to the entire
  390. syntactic context for the brace line.")
  391.  
  392. (defvar c-hanging-colons-alist nil
  393.   "*Controls the insertion of newlines before and after certain colons.
  394. This variable contains an association list with elements of the
  395. following form: (SYNTACTIC-SYMBOL . ACTION).
  396.  
  397. See the variable `c-hanging-braces-alist' for the semantics of this
  398. variable.  Note however that making ACTION a function symbol is
  399. currently not supported for this variable.")
  400.  
  401. (defvar c-hanging-semi&comma-criteria '(c-semi&comma-inside-parenlist)
  402.   "*List of functions that decide whether to insert a newline or not.
  403. The functions in this list are called, in order, whenever the
  404. auto-newline minor mode is activated (as evidenced by a `/a' or `/ah'
  405. string in the mode line), and a semicolon or comma is typed (see
  406. `c-electric-semi&comma').  Each function in this list is called with
  407. no arguments, and should return one of the following values:
  408.  
  409.   nil             -- no determination made, continue checking
  410.   'stop           -- do not insert a newline, and stop checking
  411.   (anything else) -- insert a newline, and stop checking
  412.  
  413. If every function in the list is called with no determination made,
  414. then no newline is inserted.")
  415.  
  416. (defvar c-hanging-comment-ender-p t
  417.   "*If nil, `c-fill-paragraph' leaves C block comment enders on their own line.
  418. Default value is t, which inhibits leaving block comment ending string
  419. `*/' on a line by itself.  This is BOCM's sole behavior.")
  420.  
  421. (defvar c-backslash-column 48
  422.   "*Column to insert backslashes when macroizing a region.")
  423. (defvar c-special-indent-hook nil
  424.   "*Hook for user defined special indentation adjustments.
  425. This hook gets called after a line is indented by the mode.")
  426. (defvar c-delete-function 'backward-delete-char-untabify
  427.   "*Function called by `c-electric-delete' when deleting characters.")
  428. (defvar c-electric-pound-behavior nil
  429.   "*List of behaviors for electric pound insertion.
  430. Only currently supported behavior is `alignleft'.")
  431.  
  432. (defvar c-recognize-knr-p t
  433.   "*If non-nil, `c-mode' and `objc-mode' will recognize K&R constructs.
  434. This variable is needed because of ambiguities in C syntax that make
  435. fast recognition of K&R constructs problematic, and slow.  If you are
  436. coding with ANSI prototypes, set this variable to nil to speed up
  437. recognition of certain constructs.  By setting this variable to nil, I
  438. have seen an increase of 20 times under some circumstance.")
  439.  
  440. (defvar c-progress-interval 5
  441.   "*Interval used to update progress status during long re-indentation.
  442. If a number, percentage complete gets updated after each interval of
  443. that many seconds.   Set to nil to inhibit updating.  This is only
  444. useful for Emacs 19.")
  445.  
  446. (defvar c-style-alist
  447.   '(("gnu"
  448.      (c-basic-offset . 2)
  449.      (c-comment-only-line-offset . (0 . 0))
  450.      (c-offsets-alist . ((statement-block-intro . +)
  451.              (knr-argdecl-intro . 5)
  452.              (substatement-open . +)
  453.              (label . 0)
  454.              (statement-case-open . +)
  455.              (statement-cont . +)
  456.              (arglist-intro . c-lineup-arglist-intro-after-paren)
  457.              (arglist-close . c-lineup-arglist)
  458.              ))
  459.      )
  460.     ("k&r"
  461.      (c-basic-offset . 5)
  462.      (c-comment-only-line-offset . 0)
  463.      (c-offsets-alist . ((statement-block-intro . +)
  464.              (knr-argdecl-intro . 0)
  465.              (substatement-open . 0)
  466.              (label . 0)
  467.              (statement-cont . +)
  468.              ))
  469.      )
  470.     ("bsd"
  471.      (c-basic-offset . 4)
  472.      (c-comment-only-line-offset . 0)
  473.      (c-offsets-alist . ((statement-block-intro . +)
  474.              (knr-argdecl-intro . +)
  475.              (substatement-open . 0)
  476.              (label . 0)
  477.              (statement-cont . +)
  478.              ))
  479.      )
  480.     ("stroustrup"
  481.      (c-basic-offset . 4)
  482.      (c-comment-only-line-offset . 0)
  483.      (c-offsets-alist . ((statement-block-intro . +)
  484.              (substatement-open . 0)
  485.              (label . 0)
  486.              (statement-cont . +)
  487.              ))
  488.      )
  489.     ("whitesmith"
  490.      (c-basic-offset . 4)
  491.      (c-comment-only-line-offset . 0)
  492.      (c-offsets-alist . ((statement-block-intro . +)
  493.              (knr-argdecl-intro . +)
  494.              (substatement-open . 0)
  495.              (label . 0)
  496.              (statement-cont . +)
  497.              ))
  498.  
  499.      )
  500.     ("ellemtel"
  501.      (c-basic-offset . 3)
  502.      (c-comment-only-line-offset . 0)
  503.      (c-hanging-braces-alist     . ((substatement-open before after)))
  504.      (c-offsets-alist . ((topmost-intro        . 0)
  505.                          (topmost-intro-cont   . 0)
  506.                          (substatement         . 3)
  507.              (substatement-open    . 0)
  508.              (statement-case-intro . 0)
  509.                          (case-label           . +)
  510.                          (access-label         . -3)
  511.                          (inclass              . 6)
  512.                          (inline-open          . 0)
  513.                          ))
  514.      )
  515.     ("java"
  516.      (c-basic-offset . 2)
  517.      (c-comment-only-line-offset . (0 . 0))
  518.      (c-offsets-alist . ((statement-block-intro . +)
  519.               (knr-argdecl-intro     . 5)
  520.               (substatement-open     . +)
  521.               (label                 . 0)
  522.               (statement-case-open   . +)
  523.               (statement-cont        . +)
  524.               (arglist-intro . c-lineup-arglist-intro-after-paren)
  525.               (arglist-close . c-lineup-arglist)
  526.               (access-label  . 0)
  527.              ))
  528.  
  529.      )
  530.     )
  531.   "Styles of Indentation.
  532. Elements of this alist are of the form:
  533.  
  534.   (STYLE-STRING (VARIABLE . VALUE) [(VARIABLE . VALUE) ...])
  535.  
  536. where STYLE-STRING is a short descriptive string used to select a
  537. style, VARIABLE is any cc-mode variable, and VALUE is the intended
  538. value for that variable when using the selected style.
  539.  
  540. There is one special case when VARIABLE is `c-offsets-alist'.  In this
  541. case, the VALUE is a list containing elements of the form:
  542.  
  543.   (SYNTACTIC-SYMBOL . VALUE)
  544.  
  545. as described in `c-offsets-alist'.  These are passed directly to
  546. `c-set-offset' so there is no need to set every syntactic symbol in
  547. your style, only those that are different from the default.
  548.  
  549. Note that all styles inherit from the `cc-mode' style, which is
  550. computed at the time the mode is loaded.")
  551.  
  552. (defvar c-file-style nil
  553.   "*Variable interface for setting style via File Local Variables.
  554. In a file's Local Variable section, you can set this variable to a
  555. string suitable for `c-set-style'.  When the file is visited, cc-mode
  556. will set the style of the file to this value automatically.
  557.  
  558. Note that file style settings are applied before file offset settings
  559. as designated in the variable `c-file-offsets'.")
  560.  
  561. (defvar c-file-offsets nil
  562.   "*Variable interface for setting offsets via File Local Variables.
  563. In a file's Local Variable section, you can set this variable to an
  564. association list similar to the values allowed in `c-offsets-alist'.
  565. When the file is visited, cc-mode will institute these offset settings
  566. automatically.
  567.  
  568. Note that file offset settings are applied after file style settings
  569. as designated in the variable `c-file-style'.")
  570.  
  571. (defvar c-site-default-style "gnu"
  572.   "Default style for your site.
  573. To change the default style at your site, you can set this variable to
  574. any style defined in `c-style-alist'.  However, if cc-mode is usually
  575. loaded into your Emacs at compile time, you will need to set this
  576. variable in the `site-init.el' file before cc-mode is loaded, then
  577. re-dump Emacs.")
  578.  
  579. (defvar c-mode-hook nil
  580.   "*Hook called by `c-mode'.")
  581. (defvar c++-mode-hook nil
  582.   "*Hook called by `c++-mode'.")
  583. (defvar objc-mode-hook nil
  584.   "*Hook called by `objc-mode'.")
  585. (defvar java-mode-hook nil
  586.   "*Hook called by `java-mode'.")
  587.  
  588. (defvar c-mode-common-hook nil
  589.   "*Hook called by `c-mode', `c++-mode', and 'objc-mode' during common init.")
  590.  
  591. (defvar c-mode-menu
  592.   '(["Comment Out Region"     comment-region (mark)]
  593.     ["Macro Expand Region"    c-macro-expand (mark)]
  594.     ["Backslashify"           c-backslash-region (mark)]
  595.     ["Indent Expression"      c-indent-exp
  596.      (memq (following-char) '(?\( ?\[ ?\{))]
  597.     ["Indent Line"            c-indent-command t]
  598.     ["Fill Comment Paragraph" c-fill-paragraph t]
  599.     ["Up Conditional"         c-up-conditional t]
  600.     ["Backward Conditional"   c-backward-conditional t]
  601.     ["Forward Conditional"    c-forward-conditional t]
  602.     ["Backward Statement"     c-beginning-of-statement t]
  603.     ["Forward Statement"      c-end-of-statement t]
  604.     )
  605.   "XEmacs 19 menu for C/C++/ObjC modes.")
  606.  
  607. ;; Sadly we need this for a macro in Emacs 19.
  608. (eval-when-compile
  609.   ;; Imenu isn't used in XEmacs, so just ignore load errors.
  610.   (condition-case ()
  611.       (require 'imenu)
  612.     (error nil)))
  613.  
  614. (defvar cc-imenu-c++-generic-expression
  615.   (` 
  616.    ((nil
  617.      (, 
  618.       (concat
  619.        "^"                ; beginning of line is required
  620.        "\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a "template <...>"
  621.        "\\([a-zA-Z0-9_:]+[ \t]+\\)?"    ; type specs; there can be no
  622.        "\\([a-zA-Z0-9_:]+[ \t]+\\)?"    ; more than 3 tokens, right?
  623.         
  624.        "\\("                ; last type spec including */&
  625.        "[a-zA-Z0-9_:]+"
  626.        "\\([ \t]*[*&]+[ \t]*\\|[ \t]+\\)" ; either pointer/ref sign or whitespace
  627.        "\\)?"                ; if there is a last type spec
  628.        "\\("                ; name; take that into the imenu entry
  629.        "[a-zA-Z0-9_:~]+"        ; member function, ctor or dtor...
  630.                      ; (may not contain * because then 
  631.                      ; "a::operator char*" would become "char*"!)
  632.        "\\|"
  633.        "\\([a-zA-Z0-9_:~]*::\\)?operator"
  634.        "[^a-zA-Z1-9_][^(]*"        ; ...or operator
  635.        " \\)"
  636.        "[ \t]*([^)]*)[ \t\n]*[^        ;]" ; require something other than a ; after
  637.                      ; the (...) to avoid prototypes.  Can't
  638.                      ; catch cases with () inside the parentheses
  639.                      ; surrounding the parameters
  640.                      ; (like "int foo(int a=bar()) {...}"
  641.         
  642.        )) 6)    
  643.     ("Class" 
  644.      (, (concat 
  645.       "^"                ; beginning of line is required
  646.       "\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a "template <...>"
  647.       "class[ \t]+"
  648.       "\\([a-zA-Z0-9_]+\\)"        ; this is the string we want to get
  649.       "[ \t]*[:{]"
  650.       )) 2)))
  651.   "Imenu generic expression for C++ mode.  See `imenu-generic-expression'.")
  652.  
  653. (defvar cc-imenu-c-generic-expression
  654.   cc-imenu-c++-generic-expression
  655.   "Imenu generic expression for C mode.  See `imenu-generic-expression'.")
  656.  
  657.  
  658. ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  659. ;; NO USER DEFINABLE VARIABLES BEYOND THIS POINT
  660.  
  661. ;; Shut the byte-compiler up. Requires Emacs 19 or JWZ's improved
  662. ;; byte-compiler. Otherwise, comment this line out and ignore
  663. ;; any warnings.
  664. ;;(byte-compiler-options (warnings nil))
  665.  
  666. ;; figure out what features this Emacs has
  667. (defconst c-emacs-features
  668.   (let ((major (and (boundp 'emacs-major-version)
  669.             emacs-major-version))
  670.     (minor (and (boundp 'emacs-minor-version)
  671.             emacs-minor-version))
  672.     (re-suite 'old-re)
  673.     flavor comments)
  674.     ;; figure out version numbers if not already discovered
  675.     (and (or (not major) (not minor))
  676.      (string-match "\\([0-9]+\\).\\([0-9]+\\)" emacs-version)
  677.      (setq major (string-to-int (substring emacs-version
  678.                            (match-beginning 1)
  679.                            (match-end 1)))
  680.            minor (string-to-int (substring emacs-version
  681.                            (match-beginning 2)
  682.                            (match-end 2)))))
  683.     (if (not (and major minor))
  684.     (error "Cannot figure out the major and minor version numbers."))
  685.     ;; calculate the major version
  686.     (cond
  687.      ((= major 18) (setq major 'v18))    ;Emacs 18
  688.      ((= major 4)  (setq major 'v18))    ;Epoch 4
  689.      ((= major 19) (setq major 'v19    ;Emacs 19
  690.              flavor (if (or (string-match "Lucid" emacs-version)
  691.                     (string-match "XEmacs" emacs-version))
  692.                     'XEmacs 'FSF)))
  693.      ;; I don't know
  694.      (t (error "Cannot recognize major version number: %s" major)))
  695.     ;; Regular expression suites...
  696.     (if (and (eq major 'v19)
  697.          (or (and (eq flavor 'XEmacs) (>= minor 14))
  698.          (and (eq flavor 'FSF) (>= minor 30))))
  699.     (setq re-suite 'new-re))
  700.     ;; XEmacs 19 uses 8-bit modify-syntax-entry flags, as do all
  701.     ;; patched Emacs 19, Emacs 18, Epoch 4's.  Only Emacs 19 uses a
  702.     ;; 1-bit flag.  Let's be as smart as we can about figuring this
  703.     ;; out.
  704.     (if (eq major 'v19)
  705.     (let ((table (copy-syntax-table)))
  706.       (modify-syntax-entry ?a ". 12345678" table)
  707.       (cond
  708.        ;; XEmacs pre 20 and Emacs pre 19.30 use vectors for syntax tables.
  709.        ((vectorp table)
  710.         (if (= (logand (lsh (aref table ?a) -16) 255) 255)
  711.         (setq comments '8-bit)
  712.           (setq comments '1-bit)))
  713.        ;; XEmacs 20 is known to be 8-bit
  714.        ((eq flavor 'XEmacs) (setq comments '8-bit))
  715.        ;; Emacs 19.30 and beyond are known to be 1-bit
  716.        ((eq flavor 'FSF) (setq comments '1-bit))
  717.        ;; Don't know what this is
  718.        (t (error "Couldn't figure out syntax table format."))
  719.        ))
  720.       ;; Emacs 18 has no support for dual comments
  721.       (setq comments 'no-dual-comments))
  722.     ;; lets do some minimal sanity checking.
  723.     (if (and (or
  724.           ;; Lucid Emacs before 19.6 had bugs
  725.           (and (eq major 'v19) (eq flavor 'XEmacs) (< minor 6))
  726.           ;; Emacs 19 before 19.21 has known bugs
  727.           (and (eq major 'v19) (eq flavor 'FSF) (< minor 21)))
  728.          (not c-inhibit-startup-warnings-p))
  729.     (with-output-to-temp-buffer "*cc-mode warnings*"
  730.       (print (format
  731. "The version of Emacs that you are running, %s,
  732. has known bugs in its syntax.c parsing routines which will affect the
  733. performance of cc-mode. You should strongly consider upgrading to the
  734. latest available version.  cc-mode may continue to work, after a
  735. fashion, but strange indentation errors could be encountered."
  736.              emacs-version))))
  737.     ;; Emacs 18, with no patch is not too good
  738.     (if (and (eq major 'v18) (eq comments 'no-dual-comments)
  739.          (not c-inhibit-startup-warnings-p))
  740.     (with-output-to-temp-buffer "*cc-mode warnings*"
  741.       (print (format
  742. "The version of Emacs 18 you are running, %s,
  743. has known deficiencies in its ability to handle dual C++ comments,
  744. i.e. C++ line style comments and C block style comments.  This will
  745. not be much of a problem for you if you are only editing C code, but
  746. if you are doing much C++ editing, you should strongly consider
  747. upgrading to one of the latest Emacs 19's.  In Emacs 18, you may also
  748. experience performance degradations. Emacs 19 has some new built-in
  749. routines which will speed things up for you.
  750.  
  751. Because of these inherent problems, cc-mode is no longer being
  752. actively maintained for Emacs 18, however, until you can upgrade to
  753. Emacs 19, you may want to look at cc-mode-18.el in the cc-mode
  754. distribution.  THIS FILE IS COMPLETELY UNSUPPORTED!  If you use it,
  755. you are on your own, although patch contributions will be folded into
  756. the main release."
  757.                 emacs-version))))
  758.     ;; Emacs 18 with the syntax patches are no longer supported
  759.     (if (and (eq major 'v18) (not (eq comments 'no-dual-comments))
  760.          (not c-inhibit-startup-warnings-p))
  761.     (with-output-to-temp-buffer "*cc-mode warnings*"
  762.       (print (format
  763. "You are running a syntax patched Emacs 18 variant.  While this should
  764. work for you, you may want to consider upgrading to Emacs 19.  The
  765. syntax patches are no longer supported either for syntax.c or
  766. cc-mode."))))
  767.     (list major comments re-suite))
  768.   "A list of features extant in the Emacs you are using.
  769. There are many flavors of Emacs out there, each with different
  770. features supporting those needed by cc-mode.  Here's the current
  771. supported list, along with the values for this variable:
  772.  
  773.  Emacs 18/Epoch 4:           (v18 no-dual-comments RS)
  774.  Emacs 18/Epoch 4 (patch2):  (v18 8-bit RS)
  775.  XEmacs 19:                  (v19 8-bit RS)
  776.  Emacs 19:                   (v19 1-bit RS)
  777.  
  778. RS is the regular expression suite to use.  XEmacs versions after
  779. 19.13, and Emacs versions after 19.29 use the `new-re' regex suite.
  780. All other Emacsen use the `old-re' suite.")
  781.  
  782. (defvar c++-mode-abbrev-table nil
  783.   "Abbrev table in use in c++-mode buffers.")
  784. (define-abbrev-table 'c++-mode-abbrev-table ())
  785.  
  786. (defvar c-mode-abbrev-table nil
  787.   "Abbrev table in use in c-mode buffers.")
  788. (define-abbrev-table 'c-mode-abbrev-table ())
  789.  
  790. (defvar objc-mode-abbrev-table nil
  791.   "Abbrev table in use in objc-mode buffers.")
  792. (define-abbrev-table 'objc-mode-abbrev-table ())
  793.  
  794. (defvar java-mode-abbrev-table nil
  795.   "Abbrev table in use in java-mode buffers.")
  796. (define-abbrev-table 'java-mode-abbrev-table ())
  797.  
  798. (defun c-mode-fsf-menu (name map)
  799.   ;; Add menu to a keymap.  FSF menus suck.  Don't add them for
  800.   ;; XEmacs. This feature test will fail on other than Emacs 19.
  801.   (condition-case nil
  802.       (progn
  803.     (define-key map [menu-bar] (make-sparse-keymap))
  804.     (define-key map [menu-bar c] (cons name (make-sparse-keymap name)))
  805.  
  806.     (define-key map [menu-bar c comment-region]
  807.       '("Comment Out Region" . comment-region))
  808.     (define-key map [menu-bar c c-macro-expand]
  809.       '("Macro Expand Region" . c-macro-expand))
  810.     (define-key map [menu-bar c c-backslash-region]
  811.       '("Backslashify" . c-backslash-region))
  812.     (define-key map [menu-bar c indent-exp]
  813.       '("Indent Expression" . c-indent-exp))
  814.     (define-key map [menu-bar c indent-line]
  815.       '("Indent Line" . c-indent-command))
  816.     (define-key map [menu-bar c fill]
  817.       '("Fill Comment Paragraph" . c-fill-paragraph))
  818.     (define-key map [menu-bar c up]
  819.       '("Up Conditional" . c-up-conditional))
  820.     (define-key map [menu-bar c backward]
  821.       '("Backward Conditional" . c-backward-conditional))
  822.     (define-key map [menu-bar c forward]
  823.       '("Forward Conditional" . c-forward-conditional))
  824.     (define-key map [menu-bar c backward-stmt]
  825.       '("Backward Statement" . c-beginning-of-statement))
  826.     (define-key map [menu-bar c forward-stmt]
  827.       '("Forward Statement" . c-end-of-statement))
  828.  
  829.     ;; RMS: mouse-3 should not select this menu.  mouse-3's global
  830.     ;; definition is useful in C mode and we should not interfere
  831.     ;; with that.  The menu is mainly for beginners, and for them,
  832.     ;; the menubar requires less memory than a special click.
  833.     t)
  834.     (error nil)))
  835.  
  836. (defvar c-mode-map ()
  837.   "Keymap used in c-mode buffers.")
  838. (if c-mode-map
  839.     ()
  840.   ;; TBD: should we even worry about naming this keymap. My vote: no,
  841.   ;; because Emacs and XEmacs do it differently.
  842.   (setq c-mode-map (make-sparse-keymap))
  843.   ;; put standard keybindings into MAP
  844.   ;; the following mappings correspond more or less directly to BOCM
  845.   (define-key c-mode-map "{"         'c-electric-brace)
  846.   (define-key c-mode-map "}"         'c-electric-brace)
  847.   (define-key c-mode-map ";"         'c-electric-semi&comma)
  848.   (define-key c-mode-map "#"         'c-electric-pound)
  849.   (define-key c-mode-map ":"         'c-electric-colon)
  850.   ;; Lucid Emacs 19.9 defined these two, the second of which was
  851.   ;; commented out...
  852.   ;; (define-key c-mode-map "\e{" 'c-insert-braces)
  853.   ;; Commented out electric square brackets because nobody likes them.
  854.   ;; (define-key c-mode-map "[" 'c-insert-brackets)
  855.   (define-key c-mode-map "\e\C-h"    'c-mark-function)
  856.   (define-key c-mode-map "\e\C-q"    'c-indent-exp)
  857.   (define-key c-mode-map "\ea"       'c-beginning-of-statement)
  858.   (define-key c-mode-map "\ee"       'c-end-of-statement)
  859.   ;; Emacs 19.30 introduces fill-paragraph-function, but it's not in
  860.   ;; every version of Emacs cc-mode supports.
  861.   (if (not (boundp 'fill-paragraph-function))
  862.       ;; I'd rather use an adaptive fill program instead of this.
  863.       (define-key c-mode-map "\eq"   'c-fill-paragraph))
  864.   (define-key c-mode-map "\C-c\C-n"  'c-forward-conditional)
  865.   (define-key c-mode-map "\C-c\C-p"  'c-backward-conditional)
  866.   (define-key c-mode-map "\C-c\C-u"  'c-up-conditional)
  867.   (define-key c-mode-map "\t"        'c-indent-command)
  868.   (define-key c-mode-map "\177"      'c-electric-delete)
  869.   ;; these are new keybindings, with no counterpart to BOCM
  870.   (define-key c-mode-map ","         'c-electric-semi&comma)
  871.   (define-key c-mode-map "*"         'c-electric-star)
  872.   (define-key c-mode-map "\C-c\C-q"  'c-indent-defun)
  873.   (define-key c-mode-map "\C-c\C-\\" 'c-backslash-region)
  874.   ;; TBD: where if anywhere, to put c-backward|forward-into-nomenclature
  875.   (define-key c-mode-map "\C-c\C-a"  'c-toggle-auto-state)
  876.   (define-key c-mode-map "\C-c\C-b"  'c-submit-bug-report)
  877.   (define-key c-mode-map "\C-c\C-c"  'comment-region)
  878.   (define-key c-mode-map "\C-c\C-d"  'c-toggle-hungry-state)
  879.   (define-key c-mode-map "\C-c\C-e"  'c-macro-expand)
  880.   (define-key c-mode-map "\C-c\C-o"  'c-set-offset)
  881.   (define-key c-mode-map "\C-c\C-s"  'c-show-syntactic-information)
  882.   (define-key c-mode-map "\C-c\C-t"  'c-toggle-auto-hungry-state)
  883.   ;; conflicts with OOBR
  884.   ;;(define-key c-mode-map "\C-c\C-v"  'c-version)
  885.   ;;
  886.   ;; Emacs 19 defines menus in the mode map. This call will return
  887.   ;; t on Emacs 19, otherwise no-op and return nil.
  888.   (if (and (not (c-mode-fsf-menu "C" c-mode-map))
  889.        ;; in XEmacs 19, we want the menu to popup when the 3rd
  890.        ;; button is hit.  In Lucid Emacs 19.10 and beyond this is
  891.        ;; done automatically if we put the menu on mode-popup-menu
  892.        ;; variable, see c-common-init. Emacs 19 uses C-Mouse-3 for
  893.        ;; this, and it works with no special effort.
  894.        (boundp 'current-menubar)
  895.        (not (boundp 'mode-popup-menu)))
  896.       (define-key c-mode-map 'button3 'c-popup-menu)))
  897.  
  898. (defvar c++-mode-map ()
  899.   "Keymap used in c++-mode buffers.")
  900. (if c++-mode-map
  901.     ()
  902.   ;; In Emacs 19, it makes more sense to inherit c-mode-map
  903.   (if (memq 'v19 c-emacs-features)
  904.       ;; XEmacs and Emacs 19 do this differently
  905.       (cond
  906.        ;; XEmacs 19.13
  907.        ((fboundp 'set-keymap-parents)
  908.     (setq c++-mode-map (make-sparse-keymap))
  909.     (set-keymap-parents c++-mode-map c-mode-map))
  910.        ((fboundp 'set-keymap-parent)
  911.     (setq c++-mode-map (make-sparse-keymap))
  912.     (set-keymap-parent c++-mode-map c-mode-map))
  913.        (t (setq c++-mode-map (cons 'keymap c-mode-map))))
  914.     ;; Do it the hard way for Emacs 18 -- given by JWZ
  915.     (setq c++-mode-map (nconc (make-sparse-keymap) c-mode-map)))
  916.   ;; add bindings which are only useful for C++
  917.   (define-key c++-mode-map "\C-c:"  'c-scope-operator)
  918.   (define-key c++-mode-map "/"      'c-electric-slash)
  919.   (define-key c++-mode-map "<"      'c-electric-lt-gt)
  920.   (define-key c++-mode-map ">"      'c-electric-lt-gt)
  921.   ;; Emacs 19 defines menus in the mode map. This call will return
  922.   ;; t on Emacs 19, otherwise no-op and return nil.
  923.   (c-mode-fsf-menu "C++" c++-mode-map))
  924.  
  925. (defvar objc-mode-map ()
  926.   "Keymap used in objc-mode buffers.")
  927. (if objc-mode-map
  928.     ()
  929.   ;; In Emacs 19, it makes more sense to inherit c-mode-map
  930.   (if (memq 'v19 c-emacs-features)
  931.       ;; XEmacs and Emacs 19 do this differently
  932.       (cond
  933.        ;; XEmacs 19.13
  934.        ((fboundp 'set-keymap-parents)
  935.     (setq objc-mode-map (make-sparse-keymap))
  936.     (set-keymap-parents objc-mode-map c-mode-map))
  937.        ((fboundp 'set-keymap-parent)
  938.     (setq objc-mode-map (make-sparse-keymap))
  939.     (set-keymap-parent objc-mode-map c-mode-map))
  940.        (t (setq objc-mode-map (cons 'keymap c-mode-map))))
  941.     ;; Do it the hard way for Emacs 18 -- given by JWZ
  942.     (setq objc-mode-map (nconc (make-sparse-keymap) c-mode-map)))
  943.   ;; add bindings which are only useful for Objective-C
  944.   (define-key objc-mode-map "/"      'c-electric-slash)
  945.   ;; Emacs 19 defines menus in the mode map. This call will return
  946.   ;; t on Emacs 19, otherwise no-op and return nil.
  947.   (c-mode-fsf-menu "ObjC" objc-mode-map))
  948.  
  949. (defvar java-mode-map ()
  950.   "Keymap used in java-mode buffers.")
  951. (if java-mode-map
  952.     ()
  953.   ;; In Emacs 19, it makes more sense to inherit c-mode-map
  954.   (if (memq 'v19 c-emacs-features)
  955.       ;; XEmacs and Emacs 19 do this differently
  956.       (cond
  957.        ;; XEmacs 19.13
  958.        ((fboundp 'set-keymap-parents)
  959.     (setq java-mode-map (make-sparse-keymap))
  960.     (set-keymap-parents java-mode-map c-mode-map))
  961.        ((fboundp 'set-keymap-parent)
  962.     (setq java-mode-map (make-sparse-keymap))
  963.     (set-keymap-parent java-mode-map c-mode-map))
  964.        (t (setq java-mode-map (cons 'keymap c-mode-map)))
  965.        )
  966.     ;; Do it the hard way for Emacs 18 -- given by JWZ
  967.     (setq java-mode-map (nconc (make-sparse-keymap) c-mode-map)))
  968.   ;; add bindings which are only useful for Java
  969.   (define-key java-mode-map "/"      'c-electric-slash)
  970.   ;; Emacs 19 defines menus in the mode map. This call will return t
  971.   ;; on Emacs 19, otherwise no-op and return nil.
  972.   (c-mode-fsf-menu "Java" java-mode-map))
  973.  
  974. (defun c-populate-syntax-table (table)
  975.   ;; Populate the syntax TABLE
  976.   ;; DO NOT TRY TO SET _ (UNDERSCORE) TO WORD CLASS!
  977.   (modify-syntax-entry ?_  "_"     table)
  978.   (modify-syntax-entry ?\\ "\\"    table)
  979.   (modify-syntax-entry ?+  "."     table)
  980.   (modify-syntax-entry ?-  "."     table)
  981.   (modify-syntax-entry ?=  "."     table)
  982.   (modify-syntax-entry ?%  "."     table)
  983.   (modify-syntax-entry ?<  "."     table)
  984.   (modify-syntax-entry ?>  "."     table)
  985.   (modify-syntax-entry ?&  "."     table)
  986.   (modify-syntax-entry ?|  "."     table)
  987.   (modify-syntax-entry ?\' "\""    table))
  988.  
  989. (defun c-setup-dual-comments (table)
  990.   ;; Set up TABLE to handle block and line style comments
  991.   (cond
  992.    ((memq '8-bit c-emacs-features)
  993.     ;; XEmacs 19 has the best implementation
  994.     (modify-syntax-entry ?/  ". 1456" table)
  995.     (modify-syntax-entry ?*  ". 23"   table)
  996.     (modify-syntax-entry ?\n "> b"    table)
  997.     ;; Give CR the same syntax as newline, for selective-display
  998.     (modify-syntax-entry ?\^m "> b"    table))
  999.    ((memq '1-bit c-emacs-features)
  1000.     ;; Emacs 19 does things differently, but we can work with it
  1001.     (modify-syntax-entry ?/  ". 124b" table)
  1002.     (modify-syntax-entry ?*  ". 23"   table)
  1003.     (modify-syntax-entry ?\n "> b"    table)
  1004.     ;; Give CR the same syntax as newline, for selective-display
  1005.     (modify-syntax-entry ?\^m "> b"   table))
  1006.    ))
  1007.  
  1008. (defvar c-mode-syntax-table nil
  1009.   "Syntax table used in c-mode buffers.")
  1010. (if c-mode-syntax-table
  1011.     ()
  1012.   (setq c-mode-syntax-table (make-syntax-table))
  1013.   (c-populate-syntax-table c-mode-syntax-table)
  1014.   ;; add extra comment syntax
  1015.   (modify-syntax-entry ?/  ". 14"  c-mode-syntax-table)
  1016.   (modify-syntax-entry ?*  ". 23"  c-mode-syntax-table))
  1017.  
  1018. (defvar c++-mode-syntax-table nil
  1019.   "Syntax table used in c++-mode buffers.")
  1020. (if c++-mode-syntax-table
  1021.     ()
  1022.   (setq c++-mode-syntax-table (make-syntax-table))
  1023.   (c-populate-syntax-table c++-mode-syntax-table)
  1024.   ;; add extra comment syntax
  1025.   (c-setup-dual-comments c++-mode-syntax-table)
  1026.   ;; TBD: does it make sense for colon to be symbol class in C++?
  1027.   ;; I'm not so sure, since c-label-key is busted on lines like:
  1028.   ;; Foo::bar( i );
  1029.   ;; maybe c-label-key should be fixed instead of commenting this out,
  1030.   ;; but it also bothers me that this only seems appropriate for C++
  1031.   ;; and not C.
  1032.   ;;(modify-syntax-entry ?: "_" c++-mode-syntax-table)
  1033.   )
  1034.  
  1035. (defvar objc-mode-syntax-table nil
  1036.   "Syntax table used in objc-mode buffers.")
  1037. (if objc-mode-syntax-table
  1038.     ()
  1039.   (setq objc-mode-syntax-table (make-syntax-table))
  1040.   (c-populate-syntax-table objc-mode-syntax-table)
  1041.   ;; add extra comment syntax
  1042.   (c-setup-dual-comments objc-mode-syntax-table)
  1043.   ;; everyone gets these
  1044.   (modify-syntax-entry ?@ "_" objc-mode-syntax-table)
  1045.   )
  1046.  
  1047. (defvar java-mode-syntax-table nil
  1048.   "Syntax table used in java-mode buffers.")
  1049. (if java-mode-syntax-table
  1050.     ()
  1051.   (setq java-mode-syntax-table (make-syntax-table))
  1052.   (c-populate-syntax-table java-mode-syntax-table)
  1053.   ;; add extra comment syntax
  1054.   (c-setup-dual-comments java-mode-syntax-table)
  1055.   ;; everyone gets these
  1056.   (modify-syntax-entry ?@ "_" java-mode-syntax-table)
  1057.   )
  1058.  
  1059. (defvar c-hungry-delete-key nil
  1060.   "Internal state of hungry delete key feature.")
  1061. (defvar c-auto-newline nil
  1062.   "Internal state of auto newline feature.")
  1063. (defvar c-auto-hungry-string nil
  1064.   "Internal auto-newline/hungry-delete designation string for mode line.")
  1065. (defvar c-syntactic-context nil
  1066.   "Variable containing syntactic analysis list during indentation.")
  1067. (defvar c-comment-start-regexp nil
  1068.   "Buffer local variable describing how comment are introduced.")
  1069. (defvar c-conditional-key nil
  1070.   "Buffer local language-specific conditional keyword regexp.")
  1071. (defvar c-access-key nil
  1072.   "Buffer local language-specific access key regexp.")
  1073. (defvar c-class-key nil
  1074.   "Buffer local language-specific class key regexp.")
  1075. (defvar c-method-key nil
  1076.   "Buffer local language-specific method regexp.")
  1077. (defvar c-double-slash-is-comments-p nil
  1078.   "Buffer local language-specific comment style flag.")
  1079. (defconst c-protection-key
  1080.   "\\<\\(public\\|protected\\|private\\)\\>"
  1081.   "Regexp describing protection keywords.")
  1082. (defconst c-symbol-key "\\(\\w\\|\\s_\\)+"
  1083.   "Regexp describing a C/C++/ObjC symbol.
  1084. We cannot use just `word' syntax class since `_' cannot be in word
  1085. class.  Putting underscore in word class breaks forward word movement
  1086. behavior that users are familiar with.")
  1087. (defconst c-baseclass-key
  1088.   (concat
  1089.    ":?[ \t]*\\(virtual[ \t]+\\)?\\("
  1090.    c-protection-key "[ \t]+\\)" c-symbol-key)
  1091.   "Regexp describing C++ base classes in a derived class definition.")
  1092.  
  1093. ;; minor mode variables
  1094. (make-variable-buffer-local 'c-auto-newline)
  1095. (make-variable-buffer-local 'c-hungry-delete-key)
  1096. (make-variable-buffer-local 'c-auto-hungry-string)
  1097. ;; language differences
  1098. (make-variable-buffer-local 'c-comment-start-regexp)
  1099. (make-variable-buffer-local 'c-conditional-key)
  1100. (make-variable-buffer-local 'c-access-key)
  1101. (make-variable-buffer-local 'c-class-key)
  1102. (make-variable-buffer-local 'c-method-key)
  1103. (make-variable-buffer-local 'c-double-slash-is-comments-p)
  1104. (make-variable-buffer-local 'c-baseclass-key)
  1105. (make-variable-buffer-local 'c-recognize-knr-p)
  1106. ;; style variables are made buffer local at tail end of this file.
  1107.  
  1108. ;; cmacexp is lame because it uses no preprocessor symbols.
  1109. ;; It isn't very extensible either -- hardcodes /lib/cpp.
  1110. ;; [I add it here only because c-mode has it -- BAW]
  1111. (autoload 'c-macro-expand "cmacexp"
  1112.   "Display the result of expanding all C macros occurring in the region.
  1113. The expansion is entirely correct because it uses the C preprocessor."
  1114.   t)
  1115.  
  1116.  
  1117. ;; constant regular expressions for looking at various constructs
  1118. (defconst c-C++-class-key "\\(class\\|struct\\|union\\)"
  1119.   "Regexp describing a C++ class declaration, including templates.")
  1120. (defconst c-C-class-key "\\(struct\\|union\\)"
  1121.   "Regexp describing a C struct declaration.")
  1122. (defconst c-inher-key
  1123.   (concat "\\(\\<static\\>\\s +\\)?"
  1124.       c-C++-class-key "[ \t]+" c-symbol-key
  1125.       "\\([ \t]*:[ \t]*\\)?\\s *[^;]")
  1126.   "Regexp describing a class inheritance declaration.")
  1127. (defconst c-switch-label-key
  1128.   "\\(\\(case[( \t]+\\S .*\\)\\|default[ \t]*\\):"
  1129.   "Regexp describing a switch's case or default label")
  1130. (defconst c-C++-access-key
  1131.   (concat c-protection-key ":")
  1132.   "Regexp describing C++ access specification keywords.")
  1133. (defconst c-label-key
  1134.   (concat c-symbol-key ":\\([^:]\\|$\\)")
  1135.   "Regexp describing any label.")
  1136. (defconst c-C-conditional-key
  1137.   "\\b\\(for\\|if\\|do\\|else\\|while\\|switch\\)\\b[^_]"
  1138.   "Regexp describing a conditional control.")
  1139. (defconst c-C++-conditional-key
  1140.   "\\b\\(for\\|if\\|do\\|else\\|while\\|switch\\|try\\|catch\\)\\b[^_]"
  1141.   "Regexp describing a conditional control for C++.")
  1142. (defconst c-C++-friend-key
  1143.   "friend[ \t]+\\|template[ \t]*<.+>[ \t]*friend[ \t]+"
  1144.   "Regexp describing friend declarations in C++ classes.")
  1145. (defconst c-C++-comment-start-regexp "//\\|/\\*"
  1146.   "Dual comment value for `c-comment-start-regexp'.")
  1147. (defconst c-C-comment-start-regexp "/\\*"
  1148.   "Single comment style value for `c-comment-start-regexp'.")
  1149.  
  1150. (defconst c-ObjC-method-key
  1151.   (concat
  1152.    "^\\s *[+-]\\s *"
  1153.    "\\(([^)]*)\\)?"            ; return type
  1154.    ;; \\s- in objc syntax table does not include \n
  1155.    ;; since it is considered the end of //-comments.
  1156.    "[ \t\n]*" c-symbol-key)
  1157.   "Regexp describing an Objective-C method intro.")
  1158. (defconst c-ObjC-access-key
  1159.   (concat "@" c-protection-key)
  1160.   "Regexp describing access specification keywords for Objective-C.")
  1161. (defconst c-ObjC-class-key
  1162.   (concat
  1163.    "@\\(interface\\|implementation\\)\\s +"
  1164.    c-symbol-key                ;name of the class
  1165.    "\\(\\s *:\\s *" c-symbol-key "\\)?"    ;maybe followed by the superclass
  1166.    "\\(\\s *<[^>]+>\\)?"        ;and maybe the adopted protocols list
  1167.    )
  1168.   "Regexp describing a class or protocol declaration for Objective-C.")
  1169.  
  1170. (defconst c-Java-method-key
  1171.   (concat
  1172.    "^\\s *[+-]\\s *"
  1173.    "\\(([^)]*)\\)?"            ; return type
  1174.    ;; \\s- in java syntax table does not include \n
  1175.    ;; since it is considered the end of //-comments.
  1176.    "[ \t\n]*" c-symbol-key)
  1177.   "Regexp describing a Java method intro.")
  1178. (defconst c-Java-access-key
  1179.   (concat c-protection-key)
  1180.   "Regexp describing access specification keywords for Java.")
  1181. (defconst c-Java-class-key
  1182.   (concat
  1183.    "\\(interface\\|class\\)\\s +"
  1184.    c-symbol-key                ;name of the class
  1185.    "\\(\\s *extends\\s *" c-symbol-key "\\)?" ;maybe followed by superclass 
  1186.    ;;"\\(\\s *implements *[^{]+{\\)?"    ;and maybe the adopted protocols list
  1187.    )
  1188.   "Regexp describing a class or protocol declaration for Java.")
  1189.  
  1190. ;; KLUDGE ALERT.  We default these variables to their `C' values so
  1191. ;; that non-cc-mode-ized modes that depend on c-mode will still work
  1192. ;; out of the box.  The most glaring example is awk-mode.  There ought
  1193. ;; to be a better way.
  1194. (setq-default c-conditional-key c-C-conditional-key
  1195.           c-class-key c-C-class-key
  1196.           c-comment-start-regexp c-C-comment-start-regexp)
  1197.  
  1198.  
  1199. ;; main entry points for the modes
  1200. (defconst c-list-of-mode-names nil)
  1201.  
  1202. ;;;###autoload
  1203. (defun c-mode ()
  1204.   "Major mode for editing K&R and ANSI C code.
  1205. To submit a problem report, enter `\\[c-submit-bug-report]' from a
  1206. c-mode buffer.  This automatically sets up a mail buffer with version
  1207. information already added.  You just need to add a description of the
  1208. problem, including a reproducible test case and send the message.
  1209.  
  1210. To see what version of cc-mode you are running, enter `\\[c-version]'.
  1211.  
  1212. The hook variable `c-mode-hook' is run with no args, if that value is
  1213. bound and has a non-nil value.  Also the hook `c-mode-common-hook' is
  1214. run first.
  1215.  
  1216. Key bindings:
  1217. \\{c-mode-map}"
  1218.   (interactive)
  1219.   (kill-all-local-variables)
  1220.   (set-syntax-table c-mode-syntax-table)
  1221.   (setq major-mode 'c-mode
  1222.     mode-name "C"
  1223.     local-abbrev-table c-mode-abbrev-table)
  1224.   (use-local-map c-mode-map)
  1225.   (c-common-init)
  1226.   (setq comment-start "/* "
  1227.     comment-end   " */"
  1228.     comment-multi-line t
  1229.     c-conditional-key c-C-conditional-key
  1230.     c-class-key c-C-class-key
  1231.     c-baseclass-key nil
  1232.     c-comment-start-regexp c-C-comment-start-regexp
  1233.     imenu-generic-expression cc-imenu-c-generic-expression)
  1234.   (run-hooks 'c-mode-common-hook)
  1235.   (run-hooks 'c-mode-hook))
  1236. (setq c-list-of-mode-names (cons "C" c-list-of-mode-names))
  1237.  
  1238. ;;;###autoload
  1239. (defun c++-mode ()
  1240.   "Major mode for editing C++ code.
  1241. To submit a problem report, enter `\\[c-submit-bug-report]' from a
  1242. c++-mode buffer.  This automatically sets up a mail buffer with
  1243. version information already added.  You just need to add a description
  1244. of the problem, including a reproducible test case, and send the
  1245. message.
  1246.  
  1247. To see what version of cc-mode you are running, enter `\\[c-version]'.
  1248.  
  1249. The hook variable `c++-mode-hook' is run with no args, if that
  1250. variable is bound and has a non-nil value.  Also the hook
  1251. `c-mode-common-hook' is run first.
  1252.  
  1253. Key bindings:
  1254. \\{c++-mode-map}"
  1255.   (interactive)
  1256.   (kill-all-local-variables)
  1257.   (set-syntax-table c++-mode-syntax-table)
  1258.   (setq major-mode 'c++-mode
  1259.     mode-name "C++"
  1260.     local-abbrev-table c++-mode-abbrev-table)
  1261.   (use-local-map c++-mode-map)
  1262.   (c-common-init)
  1263.   (setq comment-start "// "
  1264.     comment-end ""
  1265.     comment-multi-line nil
  1266.     c-conditional-key c-C++-conditional-key
  1267.     c-comment-start-regexp c-C++-comment-start-regexp
  1268.     c-class-key c-C++-class-key
  1269.     c-access-key c-C++-access-key
  1270.     c-double-slash-is-comments-p t
  1271.     imenu-generic-expression cc-imenu-c++-generic-expression)
  1272.   (make-local-variable 'c-recognize-knr-p)
  1273.   (setq c-recognize-knr-p nil)
  1274.   (run-hooks 'c-mode-common-hook)
  1275.   (run-hooks 'c++-mode-hook))
  1276. (setq c-list-of-mode-names (cons "C++" c-list-of-mode-names))
  1277.  
  1278. ;;;###autoload
  1279. (defun objc-mode ()
  1280.   "Major mode for editing Objective C code.
  1281. To submit a problem report, enter `\\[c-submit-bug-report]' from an
  1282. objc-mode buffer.  This automatically sets up a mail buffer with
  1283. version information already added.  You just need to add a description
  1284. of the problem, including a reproducible test case, and send the
  1285. message.
  1286.  
  1287. To see what version of cc-mode you are running, enter `\\[c-version]'.
  1288.  
  1289. The hook variable `objc-mode-hook' is run with no args, if that value
  1290. is bound and has a non-nil value.  Also the hook `c-mode-common-hook'
  1291. is run first.
  1292.  
  1293. Key bindings:
  1294. \\{objc-mode-map}"
  1295.   (interactive)
  1296.   (kill-all-local-variables)
  1297.   (set-syntax-table objc-mode-syntax-table)
  1298.   (setq major-mode 'objc-mode
  1299.     mode-name "ObjC"
  1300.     local-abbrev-table objc-mode-abbrev-table)
  1301.   (use-local-map objc-mode-map)
  1302.   (c-common-init)
  1303.   (setq comment-start "// "
  1304.     comment-end   ""
  1305.     comment-multi-line nil
  1306.     c-conditional-key c-C-conditional-key
  1307.     c-comment-start-regexp c-C++-comment-start-regexp
  1308.      c-class-key c-ObjC-class-key
  1309.     c-baseclass-key nil
  1310.     c-access-key c-ObjC-access-key
  1311.     c-double-slash-is-comments-p t
  1312.     c-method-key c-ObjC-method-key)
  1313.   (run-hooks 'c-mode-common-hook)
  1314.   (run-hooks 'objc-mode-hook))
  1315. (setq c-list-of-mode-names (cons "ObjC" c-list-of-mode-names))
  1316.  
  1317. ;;;###autoload
  1318. (defun java-mode ()
  1319.   "Major mode for editing Java code.
  1320. To submit a problem report, enter `\\[c-submit-bug-report]' from an
  1321. java-mode buffer.  This automatically sets up a mail buffer with
  1322. version information already added.  You just need to add a description
  1323. of the problem, including a reproducible test case and send the
  1324. message.
  1325.  
  1326. To see what version of cc-mode you are running, enter `\\[c-version]'.
  1327.  
  1328. The hook variable `java-mode-hook' is run with no args, if that value
  1329. is bound and has a non-nil value.  Also the common hook
  1330. `c-mode-common-hook' is run first.
  1331.  
  1332. Key bindings:
  1333. \\{java-mode-map}"
  1334.   (interactive)
  1335.   (kill-all-local-variables)
  1336.   (set-syntax-table java-mode-syntax-table)
  1337.   (setq major-mode 'java-mode
  1338.      mode-name "Java"
  1339.      local-abbrev-table java-mode-abbrev-table)
  1340.   (use-local-map java-mode-map)
  1341.   (c-common-init)
  1342.   (setq comment-start "// "
  1343.      comment-end   ""
  1344.      comment-multi-line nil
  1345.      c-conditional-key c-C-conditional-key
  1346.      c-comment-start-regexp c-C++-comment-start-regexp
  1347.       c-class-key c-Java-class-key
  1348.     c-method-key c-Java-method-key
  1349.     c-double-slash-is-comments-p t
  1350.      c-baseclass-key nil
  1351.      c-access-key c-Java-access-key)
  1352.   (c-set-style "Java")
  1353.   (run-hooks 'c-mode-common-hook)
  1354.   (run-hooks 'java-mode-hook))
  1355. (setq c-list-of-mode-names (cons "Java" c-list-of-mode-names))
  1356.  
  1357. (defun c-common-init ()
  1358.   ;; Common initializations for c++-mode and c-mode.
  1359.   ;; make local variables
  1360.   (make-local-variable 'paragraph-start)
  1361.   (make-local-variable 'paragraph-separate)
  1362.   (make-local-variable 'paragraph-ignore-fill-prefix)
  1363.   (make-local-variable 'require-final-newline)
  1364.   (make-local-variable 'parse-sexp-ignore-comments)
  1365.   (make-local-variable 'indent-line-function)
  1366.   (make-local-variable 'indent-region-function)
  1367.   (make-local-variable 'comment-start)
  1368.   (make-local-variable 'comment-end)
  1369.   (make-local-variable 'comment-column)
  1370.   (make-local-variable 'comment-start-skip)
  1371.   (make-local-variable 'comment-multi-line)
  1372.   (make-local-variable 'outline-regexp)
  1373.   (make-local-variable 'outline-level)
  1374.   (make-local-variable 'adaptive-fill-regexp)
  1375.   (make-local-variable 'imenu-generic-expression) ;set in the mode functions
  1376.   ;; Emacs 19.30 and beyond only, AFAIK
  1377.   (if (boundp 'fill-paragraph-function)
  1378.       (progn
  1379.     (make-local-variable 'fill-paragraph-function)
  1380.     (setq fill-paragraph-function 'c-fill-paragraph)))
  1381.   ;; now set their values
  1382.   (setq paragraph-start (if (memq 'new-re c-emacs-features)
  1383.                 (concat page-delimiter "\\|$")
  1384.               (concat "^$\\|" page-delimiter))
  1385.     paragraph-separate paragraph-start
  1386.     paragraph-ignore-fill-prefix t
  1387.     require-final-newline t
  1388.     parse-sexp-ignore-comments t
  1389.     indent-line-function 'c-indent-line
  1390.     indent-region-function 'c-indent-region
  1391.     outline-regexp "[^#\n\^M]"
  1392.     outline-level 'c-outline-level
  1393.     comment-column 32
  1394.     comment-start-skip "/\\*+ *\\|// *"
  1395.     adaptive-fill-regexp nil)
  1396.   ;; we have to do something special for c-offsets-alist so that the
  1397.   ;; buffer local value has its own alist structure.
  1398.   (setq c-offsets-alist (copy-alist c-offsets-alist))
  1399.   ;; setup the comment indent variable in a Emacs version portable way
  1400.   ;; ignore any byte compiler warnings you might get here
  1401.   (if (boundp 'comment-indent-function)
  1402.       (progn
  1403.        (make-local-variable 'comment-indent-function)
  1404.        (setq comment-indent-function 'c-comment-indent))
  1405.     (make-local-variable 'comment-indent-hook)
  1406.     (setq comment-indent-hook 'c-comment-indent))
  1407.   ;; Put C menu into menubar and on popup menu for XEmacs 19. I think
  1408.   ;; this happens automatically for Emacs 19.
  1409.   (if (and (boundp 'current-menubar)
  1410.        current-menubar
  1411.        (not (assoc mode-name current-menubar)))
  1412.       ;; its possible that this buffer has changed modes from one of
  1413.       ;; the other cc-mode modes.  In that case, only the menubar
  1414.       ;; title of the menu changes.
  1415.       (let ((modes (copy-sequence c-list-of-mode-names))
  1416.         changed-p)
  1417.     (setq modes (delete major-mode modes))
  1418.     (while modes
  1419.       (if (not (assoc (car modes) current-menubar))
  1420.           (setq modes (cdr modes))
  1421.         (relabel-menu-item (list (car modes)) mode-name)
  1422.         (setq modes nil
  1423.           changed-p t)))
  1424.     (if (not changed-p)
  1425.         (progn
  1426.           (set-buffer-menubar (copy-sequence current-menubar))
  1427.           (add-menu nil mode-name c-mode-menu)))))
  1428.   (if (boundp 'mode-popup-menu)
  1429.       (setq mode-popup-menu
  1430.         (cons (concat mode-name " Mode Commands") c-mode-menu)))
  1431.   ;; put auto-hungry designators onto minor-mode-alist, but only once
  1432.   (or (assq 'c-auto-hungry-string minor-mode-alist)
  1433.       (setq minor-mode-alist
  1434.         (cons '(c-auto-hungry-string c-auto-hungry-string)
  1435.           minor-mode-alist))))
  1436.  
  1437. (defun c-postprocess-file-styles ()
  1438.   "Function that post processes relevant file local variables.
  1439. Currently, this function simply applies any style and offset settings
  1440. found in the file's Local Variable list.  It first applies any style
  1441. setting found in `c-file-style', then it applies any offset settings
  1442. it finds in `c-file-offsets'."
  1443.   ;; apply file styles and offsets
  1444.   (and c-file-style
  1445.        (c-set-style c-file-style))
  1446.   (and c-file-offsets
  1447.        (mapcar
  1448.     (function
  1449.      (lambda (langentry)
  1450.        (let ((langelem (car langentry))
  1451.          (offset (cdr langentry)))
  1452.          (c-set-offset langelem offset)
  1453.          )))
  1454.     c-file-offsets)))
  1455.  
  1456. ;; Add the postprocessing function to hack-local-variables-hook.  As
  1457. ;; of 28-Aug-1995, XEmacs 19.12 and Emacs 19.29 support this.
  1458. (and (fboundp 'add-hook)
  1459.      (add-hook 'hack-local-variables-hook 'c-postprocess-file-styles))
  1460.  
  1461. (defun c-enable-//-in-c-mode ()
  1462.   "Enables // as a comment delimiter in `c-mode'.
  1463. ANSI C currently does *not* allow this, although many C compilers
  1464. support optional C++ style comments.  To use, call this function from
  1465. your `.emacs' file before you visit any C files.  The changes are
  1466. global and affect all future `c-mode' buffers."
  1467.   (c-setup-dual-comments c-mode-syntax-table)
  1468.   (setq-default c-C-comment-start-regexp c-C++-comment-start-regexp))
  1469.  
  1470.  
  1471. ;; macros must be defined before first use
  1472. (defmacro c-point (position)
  1473.   ;; Returns the value of point at certain commonly referenced POSITIONs.
  1474.   ;; POSITION can be one of the following symbols:
  1475.   ;; 
  1476.   ;; bol  -- beginning of line
  1477.   ;; eol  -- end of line
  1478.   ;; bod  -- beginning of defun
  1479.   ;; boi  -- back to indentation
  1480.   ;; ionl -- indentation of next line
  1481.   ;; iopl -- indentation of previous line
  1482.   ;; bonl -- beginning of next line
  1483.   ;; bopl -- beginning of previous line
  1484.   ;; 
  1485.   ;; This function does not modify point or mark.
  1486.   (or (and (eq 'quote (car-safe position))
  1487.        (null (cdr (cdr position))))
  1488.       (error "bad buffer position requested: %s" position))
  1489.   (setq position (nth 1 position))
  1490.   (` (let ((here (point)))
  1491.        (,@ (cond
  1492.         ((eq position 'bol)  '((beginning-of-line)))
  1493.         ((eq position 'eol)  '((end-of-line)))
  1494.         ((eq position 'bod)
  1495.          '((beginning-of-defun)
  1496.            ;; if defun-prompt-regexp is non-nil, b-o-d won't leave
  1497.            ;; us at the open brace.
  1498.            (and (boundp 'defun-prompt-regexp)
  1499.             defun-prompt-regexp
  1500.             (looking-at defun-prompt-regexp)
  1501.             (goto-char (match-end 0)))
  1502.            ))
  1503.         ((eq position 'boi)  '((back-to-indentation)))
  1504.         ((eq position 'bonl) '((forward-line 1)))
  1505.         ((eq position 'bopl) '((forward-line -1)))
  1506.         ((eq position 'iopl)
  1507.          '((forward-line -1)
  1508.            (back-to-indentation)))
  1509.         ((eq position 'ionl)
  1510.          '((forward-line 1)
  1511.            (back-to-indentation)))
  1512.         (t (error "unknown buffer position requested: %s" position))
  1513.         ))
  1514.        (prog1
  1515.        (point)
  1516.      (goto-char here))
  1517.        ;; workaround for an Emacs18 bug -- blech! Well, at least it
  1518.        ;; doesn't hurt for v19
  1519.        (,@ nil)
  1520.        )))
  1521.  
  1522. (defmacro c-auto-newline ()
  1523.   ;; if auto-newline feature is turned on, insert a newline character
  1524.   ;; and return t, otherwise return nil.
  1525.   (` (and c-auto-newline
  1526.       (not (c-in-literal))
  1527.       (not (newline)))))
  1528.  
  1529. (defmacro c-safe (&rest body)
  1530.   ;; safely execute BODY, return nil if an error occurred
  1531.   (` (condition-case nil
  1532.      (progn (,@ body))
  1533.        (error nil))))
  1534.  
  1535. (defun c-insert-special-chars (arg)
  1536.   ;; simply call self-insert-command in Emacs 19
  1537.   (self-insert-command (prefix-numeric-value arg)))
  1538.  
  1539. (defun c-intersect-lists (list alist)
  1540.   ;; return the element of ALIST that matches the first element found
  1541.   ;; in LIST.  Uses assq.
  1542.   (let (match)
  1543.     (while (and list
  1544.         (not (setq match (assq (car list) alist))))
  1545.       (setq list (cdr list)))
  1546.     match))
  1547.  
  1548. (defun c-lookup-lists (list alist1 alist2)
  1549.   ;; first, find the first entry from LIST that is present in ALIST1,
  1550.   ;; then find the entry in ALIST2 for that entry.
  1551.   (assq (car (c-intersect-lists list alist1)) alist2))
  1552.  
  1553.  
  1554. ;; This is used by indent-for-comment to decide how much to indent a
  1555. ;; comment in C code based on its context.
  1556. (defun c-comment-indent ()
  1557.   (if (looking-at (concat "^\\(" c-comment-start-regexp "\\)"))
  1558.       0                ;Existing comment at bol stays there.
  1559.     (let ((opoint (point))
  1560.       placeholder)
  1561.       (save-excursion
  1562.     (beginning-of-line)
  1563.     (cond
  1564.      ;; CASE 1: A comment following a solitary close-brace should
  1565.      ;; have only one space.
  1566.      ((looking-at (concat "[ \t]*}[ \t]*\\($\\|"
  1567.                   c-comment-start-regexp
  1568.                   "\\)"))
  1569.       (search-forward "}")
  1570.       (1+ (current-column)))
  1571.      ;; CASE 2: 2 spaces after #endif
  1572.      ((or (looking-at "^#[ \t]*endif[ \t]*")
  1573.           (looking-at "^#[ \t]*else[ \t]*"))
  1574.       7)
  1575.      ;; CASE 3: when comment-column is nil, calculate the offset
  1576.      ;; according to c-offsets-alist.  E.g. identical to hitting
  1577.      ;; TAB.
  1578.      ((and c-indent-comments-syntactically-p
  1579.            (save-excursion
  1580.          (skip-chars-forward " \t")
  1581.          (or (looking-at comment-start)
  1582.              (eolp))))
  1583.       (let ((syntax (c-guess-basic-syntax)))
  1584.         ;; BOGOSITY ALERT: if we're looking at the eol, its
  1585.         ;; because indent-for-comment hasn't put the comment-start
  1586.         ;; in the buffer yet.  this will screw up the syntactic
  1587.         ;; analysis so we kludge in the necessary info.  Another
  1588.         ;; kludge is that if we're at the bol, then we really want
  1589.         ;; to ignore any anchoring as specified by
  1590.         ;; c-comment-only-line-offset since it doesn't apply here.
  1591.         (if (save-excursion
  1592.           (beginning-of-line)
  1593.           (skip-chars-forward " \t")
  1594.           (eolp))
  1595.         (c-add-syntax 'comment-intro))
  1596.         (let ((c-comment-only-line-offset
  1597.            (if (consp c-comment-only-line-offset)
  1598.                c-comment-only-line-offset
  1599.              (cons c-comment-only-line-offset
  1600.                c-comment-only-line-offset))))
  1601.           (apply '+ (mapcar 'c-get-offset syntax)))))
  1602.      ;; CASE 4: use comment-column if previous line is a
  1603.      ;; comment-only line indented to the left of comment-column
  1604.      ((save-excursion
  1605.         (beginning-of-line)
  1606.         (and (not (bobp))
  1607.          (forward-line -1))
  1608.         (skip-chars-forward " \t")
  1609.         (prog1
  1610.         (looking-at c-comment-start-regexp)
  1611.           (setq placeholder (point))))
  1612.       (goto-char placeholder)
  1613.       (if (< (current-column) comment-column)
  1614.           comment-column
  1615.         (current-column)))
  1616.      ;; CASE 5: If comment-column is 0, and nothing but space
  1617.      ;; before the comment, align it at 0 rather than 1.
  1618.      ((progn
  1619.         (goto-char opoint)
  1620.         (skip-chars-backward " \t")
  1621.         (and (= comment-column 0) (bolp)))
  1622.       0)
  1623.      ;; CASE 6: indent at comment column except leave at least one
  1624.      ;; space.
  1625.      (t (max (1+ (current-column))
  1626.          comment-column))
  1627.      )))))
  1628.  
  1629. ;; used by outline-minor-mode
  1630. (defun c-outline-level ()
  1631.   (save-excursion
  1632.     (skip-chars-forward "\t ")
  1633.     (current-column)))
  1634.  
  1635. ;; active regions, and auto-newline/hungry delete key
  1636. (defun c-keep-region-active ()
  1637.   ;; Do whatever is necessary to keep the region active in
  1638.   ;; XEmacs 19. ignore byte-compiler warnings you might see
  1639.   (and (boundp 'zmacs-region-stays)
  1640.        (setq zmacs-region-stays t)))
  1641.  
  1642. (defun c-update-modeline ()
  1643.   ;; set the c-auto-hungry-string for the correct designation on the modeline
  1644.   (setq c-auto-hungry-string
  1645.     (if c-auto-newline
  1646.         (if c-hungry-delete-key "/ah" "/a")
  1647.       (if c-hungry-delete-key "/h" nil)))
  1648.   ;; updates the modeline for all Emacsen
  1649.   (if (memq 'v19 c-emacs-features)
  1650.       (force-mode-line-update)
  1651.     (set-buffer-modified-p (buffer-modified-p))))
  1652.  
  1653. (defun c-calculate-state (arg prevstate)
  1654.   ;; Calculate the new state of PREVSTATE, t or nil, based on arg. If
  1655.   ;; arg is nil or zero, toggle the state. If arg is negative, turn
  1656.   ;; the state off, and if arg is positive, turn the state on
  1657.   (if (or (not arg)
  1658.       (zerop (setq arg (prefix-numeric-value arg))))
  1659.       (not prevstate)
  1660.     (> arg 0)))
  1661.  
  1662. (defun c-toggle-auto-state (arg)
  1663.   "Toggle auto-newline feature.
  1664. Optional numeric ARG, if supplied turns on auto-newline when positive,
  1665. turns it off when negative, and just toggles it when zero.
  1666.  
  1667. When the auto-newline feature is enabled (as evidenced by the `/a' or
  1668. `/ah' on the modeline after the mode name) newlines are automatically
  1669. inserted after special characters such as brace, comma, semi-colon,
  1670. and colon."
  1671.   (interactive "P")
  1672.   (setq c-auto-newline (c-calculate-state arg c-auto-newline))
  1673.   (c-update-modeline)
  1674.   (c-keep-region-active))
  1675.  
  1676. (defun c-toggle-hungry-state (arg)
  1677.   "Toggle hungry-delete-key feature.
  1678. Optional numeric ARG, if supplied turns on hungry-delete when positive,
  1679. turns it off when negative, and just toggles it when zero.
  1680.  
  1681. When the hungry-delete-key feature is enabled (as evidenced by the
  1682. `/h' or `/ah' on the modeline after the mode name) the delete key
  1683. gobbles all preceding whitespace in one fell swoop."
  1684.   (interactive "P")
  1685.   (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
  1686.   (c-update-modeline)
  1687.   (c-keep-region-active))
  1688.  
  1689. (defun c-toggle-auto-hungry-state (arg)
  1690.   "Toggle auto-newline and hungry-delete-key features.
  1691. Optional numeric ARG, if supplied turns on auto-newline and
  1692. hungry-delete when positive, turns them off when negative, and just
  1693. toggles them when zero.
  1694.  
  1695. See `c-toggle-auto-state' and `c-toggle-hungry-state' for details."
  1696.   (interactive "P")
  1697.   (setq c-auto-newline (c-calculate-state arg c-auto-newline))
  1698.   (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
  1699.   (c-update-modeline)
  1700.   (c-keep-region-active))
  1701.  
  1702.  
  1703. ;; COMMANDS
  1704. (defun c-electric-delete (arg)
  1705.   "Deletes preceding character or whitespace.
  1706. If `c-hungry-delete-key' is non-nil, as evidenced by the \"/h\" or
  1707. \"/ah\" string on the mode line, then all preceding whitespace is
  1708. consumed.  If however an ARG is supplied, or `c-hungry-delete-key' is
  1709. nil, or point is inside a literal then the function in the variable
  1710. `c-delete-function' is called."
  1711.   (interactive "P")
  1712.   (if (or (not c-hungry-delete-key)
  1713.       arg
  1714.       (c-in-literal))
  1715.       (funcall c-delete-function (prefix-numeric-value arg))
  1716.     (let ((here (point)))
  1717.       (skip-chars-backward " \t\n")
  1718.       (if (/= (point) here)
  1719.       (delete-region (point) here)
  1720.     (funcall c-delete-function 1)
  1721.     ))))
  1722.  
  1723. (defun c-electric-pound (arg)
  1724.   "Electric pound (`#') insertion.
  1725. Inserts a `#' character specially depending on the variable
  1726. `c-electric-pound-behavior'.  If a numeric ARG is supplied, or if
  1727. point is inside a literal, nothing special happens."
  1728.   (interactive "P")
  1729.   (if (or (c-in-literal)
  1730.       arg
  1731.       (not (memq 'alignleft c-electric-pound-behavior)))
  1732.       ;; do nothing special
  1733.       (self-insert-command (prefix-numeric-value arg))
  1734.     ;; place the pound character at the left edge
  1735.     (let ((pos (- (point-max) (point)))
  1736.       (bolp (bolp)))
  1737.       (beginning-of-line)
  1738.       (delete-horizontal-space)
  1739.       (insert-char last-command-char 1)
  1740.       (and (not bolp)
  1741.        (goto-char (- (point-max) pos)))
  1742.       )))
  1743.  
  1744. (defun c-electric-brace (arg)
  1745.   "Insert a brace.
  1746.  
  1747. If the auto-newline feature is turned on, as evidenced by the \"/a\"
  1748. or \"/ah\" string on the mode line, newlines are inserted before and
  1749. after braces based on the value of `c-hanging-braces-alist'.
  1750.  
  1751. Also, the line is re-indented unless a numeric ARG is supplied, there
  1752. are non-whitespace characters present on the line after the brace, or
  1753. the brace is inserted inside a literal."
  1754.   (interactive "P")
  1755.   (let* ((c-state-cache (c-parse-state))
  1756.      (safepos (c-safe-position (point) c-state-cache))
  1757.      (literal (c-in-literal safepos)))
  1758.     ;; if we're in a literal, or we're not at the end of the line, or
  1759.     ;; a numeric arg is provided, or auto-newlining is turned off,
  1760.     ;; then just insert the character.
  1761.     (if (or literal arg
  1762. ;        (not c-auto-newline)
  1763.         (not (looking-at "[ \t]*$")))
  1764.     (c-insert-special-chars arg)    
  1765.       (let* ((syms '(class-open class-close defun-open defun-close 
  1766.              inline-open inline-close brace-list-open brace-list-close
  1767.              brace-list-intro brace-list-entry block-open block-close
  1768.              substatement-open statement-case-open))
  1769.         ;; we want to inhibit blinking the paren since this will
  1770.         ;; be most disruptive. we'll blink it ourselves later on
  1771.         (old-blink-paren (if (boundp 'blink-paren-function)
  1772.                  blink-paren-function
  1773.                    blink-paren-hook))
  1774.         blink-paren-function    ; emacs19
  1775.         blink-paren-hook        ; emacs18
  1776.         (insertion-point (point))
  1777.         delete-temp-newline
  1778.         (preserve-p (= 32 (char-syntax (preceding-char))))
  1779.         ;; shut this up too
  1780.         (c-echo-syntactic-information-p nil)
  1781.         (syntax (progn
  1782.               ;; only insert a newline if there is
  1783.               ;; non-whitespace behind us
  1784.               (if (save-excursion
  1785.                 (skip-chars-backward " \t")
  1786.                 (not (bolp)))
  1787.               (progn (newline)
  1788.                  (setq delete-temp-newline t)))
  1789.               (self-insert-command (prefix-numeric-value arg))
  1790.               ;; state cache doesn't change
  1791.               (c-guess-basic-syntax)))
  1792.         (newlines (and
  1793.                c-auto-newline
  1794.                (or (c-lookup-lists syms syntax c-hanging-braces-alist)
  1795.                '(ignore before after)))))
  1796.     ;; If syntax is a function symbol, then call it using the
  1797.     ;; defined semantics.
  1798.     (if (and (not (consp (cdr newlines)))
  1799.          (fboundp (cdr newlines)))
  1800.         (let ((c-syntactic-context syntax))
  1801.           (setq newlines
  1802.             (funcall (cdr newlines) (car newlines) insertion-point))))
  1803.     ;; does a newline go before the open brace?
  1804.     (if (memq 'before newlines)
  1805.         ;; we leave the newline we've put in there before,
  1806.         ;; but we need to re-indent the line above
  1807.         (let ((pos (- (point-max) (point)))
  1808.           (here (point))
  1809.           (c-state-cache c-state-cache))
  1810.           (forward-line -1)
  1811.           ;; we may need to update the cache. this should still be
  1812.           ;; faster than recalculating the state in many cases
  1813.           (save-excursion
  1814.         (save-restriction
  1815.           (narrow-to-region here (point))
  1816.           (if (and (c-safe (progn (backward-up-list -1) t))
  1817.                (memq (preceding-char) '(?\) ?}))
  1818.                (progn (widen)
  1819.                   (c-safe (progn (forward-sexp -1) t))))
  1820.               (setq c-state-cache
  1821.                 (c-hack-state (point) 'open c-state-cache))
  1822.             (if (and (car c-state-cache)
  1823.                  (not (consp (car c-state-cache)))
  1824.                  (<= (point) (car c-state-cache)))
  1825.             (setq c-state-cache (cdr c-state-cache))
  1826.               ))))
  1827.           (let ((here (point))
  1828.             (shift (c-indent-line)))
  1829.         (setq c-state-cache (c-adjust-state (c-point 'bol) here
  1830.                             (- shift) c-state-cache)))
  1831.           (goto-char (- (point-max) pos))
  1832.           ;; if the buffer has changed due to the indentation, we
  1833.           ;; need to recalculate syntax for the current line, but
  1834.           ;; we won't need to update the state cache.
  1835.           (if (/= (point) here)
  1836.           (setq syntax (c-guess-basic-syntax))))
  1837.       ;; must remove the newline we just stuck in (if we really did it)
  1838.       (and delete-temp-newline
  1839.            (save-excursion
  1840.          ;; if there is whitespace before point, then preserve
  1841.          ;; at least one space.
  1842.          (delete-indentation)
  1843.          (just-one-space)
  1844.          (if (not preserve-p)
  1845.              (delete-char -1))))
  1846.       ;; since we're hanging the brace, we need to recalculate
  1847.       ;; syntax.  Update the state to accurately reflect the
  1848.       ;; beginning of the line.  We punt if we cross any open or
  1849.       ;; closed parens because its just too hard to modify the
  1850.       ;; known state.  This limitation will be fixed in v5.
  1851.       (save-excursion
  1852.         (let ((bol (c-point 'bol)))
  1853.           (if (zerop (car (parse-partial-sexp bol (1- (point)))))
  1854.           (setq c-state-cache (c-whack-state bol c-state-cache)
  1855.             syntax (c-guess-basic-syntax))
  1856.         ;; gotta punt. this requires some horrible kludgery
  1857.         (beginning-of-line)
  1858.         (makunbound 'c-state-cache)
  1859.         (setq c-state-cache (c-parse-state)
  1860.               syntax nil))))
  1861.       )
  1862.     ;; now adjust the line's indentation. don't update the state
  1863.     ;; cache since c-guess-basic-syntax isn't called when the
  1864.     ;; syntax is passed to c-indent-line
  1865.     (let ((here (point))
  1866.           (shift (c-indent-line syntax)))
  1867.       (setq c-state-cache (c-adjust-state (c-point 'bol) here
  1868.                           (- shift) c-state-cache)))
  1869.     ;; Do all appropriate clean ups
  1870.     (let ((here (point))
  1871.           (pos (- (point-max) (point)))
  1872.           mbeg mend)
  1873.       ;; clean up empty defun braces
  1874.       (if (and c-auto-newline
  1875.            (memq 'empty-defun-braces c-cleanup-list)
  1876.            (= last-command-char ?\})
  1877.            (c-intersect-lists '(defun-close class-close inline-close)
  1878.                       syntax)
  1879.            (progn
  1880.              (forward-char -1)
  1881.              (skip-chars-backward " \t\n")
  1882.              (= (preceding-char) ?\{))
  1883.            ;; make sure matching open brace isn't in a comment
  1884.            (not (c-in-literal)))
  1885.           (delete-region (point) (1- here)))
  1886.       ;; clean up brace-else-brace
  1887.       (if (and c-auto-newline
  1888.            (memq 'brace-else-brace c-cleanup-list)
  1889.            (= last-command-char ?\{)
  1890.            (re-search-backward "}[ \t\n]*else[ \t\n]*{" nil t)
  1891.            (progn
  1892.              (setq mbeg (match-beginning 0)
  1893.                mend (match-end 0))
  1894.              (= mend here))
  1895.            (not (c-in-literal)))
  1896.           (progn
  1897.         (delete-region mbeg mend)
  1898.         (insert "} else {")))
  1899.       (goto-char (- (point-max) pos))
  1900.       )
  1901.     ;; does a newline go after the brace?
  1902.     (if (memq 'after newlines)
  1903.         (progn
  1904.           (newline)
  1905.           ;; update on c-state-cache
  1906.           (let* ((bufpos (- (point) 2))
  1907.              (which (if (= (char-after bufpos) ?{) 'open 'close))
  1908.              (c-state-cache (c-hack-state bufpos which c-state-cache)))
  1909.         (c-indent-line))))
  1910.     ;; blink the paren
  1911.     (and (= last-command-char ?\})
  1912.          old-blink-paren
  1913.          (save-excursion
  1914.            (c-backward-syntactic-ws safepos)
  1915.            (if (boundp 'blink-paren-function)
  1916.            (funcall old-blink-paren)
  1917.          (run-hooks old-blink-paren))))
  1918.     ))))
  1919.       
  1920. (defun c-electric-slash (arg)
  1921.   "Insert a slash character.
  1922. If slash is second of a double-slash C++ style comment introducing
  1923. construct, and we are on a comment-only-line, indent line as comment.
  1924. If numeric ARG is supplied or point is inside a literal, indentation
  1925. is inhibited."
  1926.   (interactive "P")
  1927.   (let ((indentp (and (not arg)
  1928.               (= (preceding-char) ?/)
  1929.               (= last-command-char ?/)
  1930.               (not (c-in-literal))))
  1931.     ;; shut this up
  1932.     (c-echo-syntactic-information-p nil))
  1933.     (self-insert-command (prefix-numeric-value arg))
  1934.     (if indentp
  1935.     (c-indent-line))))
  1936.  
  1937. (defun c-electric-star (arg)
  1938.   "Insert a star character.
  1939. If the star is the second character of a C style comment introducing
  1940. construct, and we are on a comment-only-line, indent line as comment.
  1941. If numeric ARG is supplied or point is inside a literal, indentation
  1942. is inhibited."
  1943.   (interactive "P")
  1944.   (self-insert-command (prefix-numeric-value arg))
  1945.   ;; if we are in a literal, or if arg is given do not re-indent the
  1946.   ;; current line, unless this star introduces a comment-only line.
  1947.   (if (and (not arg)
  1948.        (memq (c-in-literal) '(c))
  1949.        (= (preceding-char) ?*)
  1950.        (save-excursion
  1951.          (forward-char -1)
  1952.          (skip-chars-backward "*")
  1953.          (if (= (preceding-char) ?/)
  1954.          (forward-char -1))
  1955.          (skip-chars-backward " \t")
  1956.          (bolp)))
  1957.       ;; shut this up
  1958.       (let (c-echo-syntactic-information-p)
  1959.     (c-indent-line))
  1960.     ))
  1961.  
  1962. (defun c-electric-semi&comma (arg)
  1963.   "Insert a comma or semicolon.
  1964. When the auto-newline feature is turned on, as evidenced by the \"/a\"
  1965. or \"/ah\" string on the mode line, a newline might be inserted.  See
  1966. the variable `c-hanging-semi&comma-criteria' for how newline insertion
  1967. is determined.
  1968.  
  1969. When semicolon is inserted, the line is re-indented unless a numeric
  1970. arg is supplied, point is inside a literal, or there are
  1971. non-whitespace characters on the line following the semicolon."
  1972.   (interactive "P")
  1973.   (let* ((lim (c-most-enclosing-brace (c-parse-state)))
  1974.      (literal (c-in-literal lim))
  1975.      (here (point))
  1976.      ;; shut this up
  1977.      (c-echo-syntactic-information-p nil))
  1978.     (if (or literal
  1979.         arg
  1980.         (not (looking-at "[ \t]*$")))
  1981.     (c-insert-special-chars arg)
  1982.       ;; do some special stuff with the character
  1983.       (self-insert-command (prefix-numeric-value arg))
  1984.       ;; do all cleanups, reindentations, and newline insertions, but
  1985.       ;; only if c-auto-newline is turned on
  1986.       (if (not c-auto-newline) nil
  1987.     ;; clean ups
  1988.     (let ((pos (- (point-max) (point))))
  1989.       (if (and (or (and
  1990.             (= last-command-char ?,)
  1991.             (memq 'list-close-comma c-cleanup-list))
  1992.                (and
  1993.             (= last-command-char ?\;)
  1994.             (memq 'defun-close-semi c-cleanup-list)))
  1995.            (progn
  1996.              (forward-char -1)
  1997.              (skip-chars-backward " \t\n")
  1998.              (= (preceding-char) ?}))
  1999.            ;; make sure matching open brace isn't in a comment
  2000.            (not (c-in-literal lim)))
  2001.           (delete-region (point) here))
  2002.       (goto-char (- (point-max) pos)))
  2003.     ;; re-indent line
  2004.     (c-indent-line)
  2005.     ;; check to see if a newline should be added
  2006.     (let ((criteria c-hanging-semi&comma-criteria)
  2007.           answer add-newline-p)
  2008.       (while criteria
  2009.         (setq answer (funcall (car criteria)))
  2010.         ;; only nil value means continue checking
  2011.         (if (not answer)
  2012.         (setq criteria (cdr criteria))
  2013.           (setq criteria nil)
  2014.           ;; only 'stop specifically says do not add a newline
  2015.           (setq add-newline-p (not (eq answer 'stop)))
  2016.           ))
  2017.       (if add-newline-p
  2018.           (progn (newline)
  2019.              (c-indent-line)))
  2020.       )))))
  2021.  
  2022. (defun c-semi&comma-inside-parenlist ()
  2023.   "Determine if a newline should be added after a semicolon.
  2024. If a comma was inserted, no determination is made.  If a semicolon was
  2025. inserted inside a parenthesis list, no newline is added otherwise a
  2026. newline is added.  In either case, checking is stopped.  This supports
  2027. exactly the old newline insertion behavior."
  2028.   ;; newline only after semicolon, but only if that semicolon is not
  2029.   ;; inside a parenthesis list (e.g. a for loop statement)
  2030.   (if (/= last-command-char ?\;)
  2031.       nil                ; continue checking
  2032.     (if (condition-case nil
  2033.         (save-excursion
  2034.           (up-list -1)
  2035.           (/= (following-char) ?\())
  2036.       (error t))
  2037.     t
  2038.       'stop)))
  2039.  
  2040. (defun c-electric-colon (arg)
  2041.   "Insert a colon.
  2042.  
  2043. If the auto-newline feature is turned on, as evidenced by the \"/a\"
  2044. or \"/ah\" string on the mode line, newlines are inserted before and
  2045. after colons based on the value of `c-hanging-colons-alist'.
  2046.  
  2047. Also, the line is re-indented unless a numeric ARG is supplied, there
  2048. are non-whitespace characters present on the line after the colon, or
  2049. the colon is inserted inside a literal.
  2050.  
  2051. This function cleans up double colon scope operators based on the
  2052. value of `c-cleanup-list'."
  2053.   (interactive "P")
  2054.   (let* ((bod (c-point 'bod))
  2055.      (literal (c-in-literal bod))
  2056.      syntax newlines
  2057.      ;; shut this up
  2058.      (c-echo-syntactic-information-p nil))
  2059.     (if (or literal
  2060.         arg
  2061.         (not (looking-at "[ \t]*$")))
  2062.     (c-insert-special-chars arg)
  2063.       ;; insert the colon, then do any specified cleanups
  2064.       (self-insert-command (prefix-numeric-value arg))
  2065.       (let ((pos (- (point-max) (point)))
  2066.         (here (point)))
  2067.     (if (and c-auto-newline
  2068.          (memq 'scope-operator c-cleanup-list)
  2069.          (= (preceding-char) ?:)
  2070.          (progn
  2071.            (forward-char -1)
  2072.            (skip-chars-backward " \t\n")
  2073.            (= (preceding-char) ?:))
  2074.          (not (c-in-literal))
  2075.          (not (= (char-after (- (point) 2)) ?:)))
  2076.         (delete-region (point) (1- here)))
  2077.     (goto-char (- (point-max) pos)))
  2078.       ;; lets do some special stuff with the colon character
  2079.       (setq syntax (c-guess-basic-syntax)
  2080.         ;; some language elements can only be determined by
  2081.         ;; checking the following line.  Lets first look for ones
  2082.         ;; that can be found when looking on the line with the
  2083.         ;; colon
  2084.         newlines
  2085.         (and c-auto-newline
  2086.          (or (c-lookup-lists '(case-label label access-label)
  2087.                      syntax c-hanging-colons-alist)
  2088.              (c-lookup-lists '(member-init-intro inher-intro)
  2089.                      (prog2
  2090.                      (insert "\n")
  2091.                      (c-guess-basic-syntax)
  2092.                        (delete-char -1))
  2093.                      c-hanging-colons-alist))))
  2094.       ;; indent the current line
  2095.       (c-indent-line syntax)
  2096.       ;; does a newline go before the colon?  Watch out for already
  2097.       ;; non-hung colons.  However, we don't unhang them because that
  2098.       ;; would be a cleanup (and anti-social).
  2099.       (if (and (memq 'before newlines)
  2100.            (save-excursion
  2101.          (skip-chars-backward ": \t")
  2102.          (not (bolp))))
  2103.       (let ((pos (- (point-max) (point))))
  2104.         (forward-char -1)
  2105.         (newline)
  2106.         (c-indent-line)
  2107.         (goto-char (- (point-max) pos))))
  2108.       ;; does a newline go after the colon?
  2109.       (if (memq 'after (cdr-safe newlines))
  2110.       (progn
  2111.         (newline)
  2112.         (c-indent-line)))
  2113.       )))
  2114.  
  2115. (defun c-electric-lt-gt (arg)
  2116.   "Insert a less-than, or greater-than character.
  2117. When the auto-newline feature is turned on, as evidenced by the \"/a\"
  2118. or \"/ah\" string on the mode line, the line will be re-indented if
  2119. the character inserted is the second of a C++ style stream operator
  2120. and the buffer is in C++ mode.
  2121.  
  2122. The line will also not be re-indented if a numeric argument is
  2123. supplied, or point is inside a literal."
  2124.   (interactive "P")
  2125.   (let ((indentp (and (not arg)
  2126.               (= (preceding-char) last-command-char)
  2127.               (not (c-in-literal))))
  2128.     ;; shut this up
  2129.     (c-echo-syntactic-information-p nil))
  2130.     (self-insert-command (prefix-numeric-value arg))
  2131.     (if indentp
  2132.     (c-indent-line))))
  2133.  
  2134. ;; set up electric character functions to work with pending-del,
  2135. ;; (a.k.a. delsel) mode.  All symbols get the t value except
  2136. ;; c-electric-delete which gets 'supersede.
  2137. (mapcar
  2138.  (function
  2139.   (lambda (sym)
  2140.     (put sym 'delete-selection t)    ; for delsel (Emacs)
  2141.     (put sym 'pending-delete t)))    ; for pending-del (XEmacs)
  2142.  '(c-electric-pound
  2143.    c-electric-brace
  2144.    c-electric-slash
  2145.    c-electric-star
  2146.    c-electric-semi&comma
  2147.    c-electric-lt-gt
  2148.    c-electric-colon))
  2149. (put 'c-electric-delete 'delete-selection 'supersede) ; delsel
  2150. (put 'c-electric-delete 'pending-delete   'supersede) ; pending-del
  2151.  
  2152.  
  2153.  
  2154. (defun c-read-offset (langelem)
  2155.   ;; read new offset value for LANGELEM from minibuffer. return a
  2156.   ;; legal value only
  2157.   (let* ((oldoff (cdr-safe (assq langelem c-offsets-alist)))
  2158.      (defstr (format "(default %s): " oldoff))
  2159.      (errmsg (concat "Offset must be int, func, var, "
  2160.              "or in [+,-,++,--,*,/] "
  2161.              defstr))
  2162.      (prompt (concat "Offset " defstr))
  2163.      offset input interned)
  2164.     (while (not offset)
  2165.       (setq input (read-string prompt)
  2166.         offset (cond ((string-equal "" input) oldoff)  ; default
  2167.              ((string-equal "+" input) '+)
  2168.              ((string-equal "-" input) '-)
  2169.              ((string-equal "++" input) '++)
  2170.              ((string-equal "--" input) '--)
  2171.              ((string-equal "*" input) '*)
  2172.              ((string-equal "/" input) '/)
  2173.              ((string-match "^-?[0-9]+$" input)
  2174.               (string-to-int input))
  2175.              ((fboundp (setq interned (intern input)))
  2176.               interned)
  2177.              ((boundp interned) interned)
  2178.              ;; error, but don't signal one, keep trying
  2179.              ;; to read an input value
  2180.              (t (ding)
  2181.                 (setq prompt errmsg)
  2182.                 nil))))
  2183.     offset))
  2184.  
  2185. (defun c-set-offset (symbol offset &optional add-p)
  2186.   "Change the value of a syntactic element symbol in `c-offsets-alist'.
  2187. SYMBOL is the syntactic element symbol to change and OFFSET is the new
  2188. offset for that syntactic element.  Optional ADD says to add SYMBOL to
  2189. `c-offsets-alist' if it doesn't already appear there."
  2190.   (interactive
  2191.    (let* ((langelem
  2192.        (intern (completing-read
  2193.             (concat "Syntactic symbol to change"
  2194.                 (if current-prefix-arg " or add" "")
  2195.                 ": ")
  2196.             (mapcar
  2197.              (function
  2198.               (lambda (langelem)
  2199.             (cons (format "%s" (car langelem)) nil)))
  2200.              c-offsets-alist)
  2201.             nil (not current-prefix-arg)
  2202.             ;; initial contents tries to be the last element
  2203.             ;; on the syntactic analysis list for the current
  2204.             ;; line
  2205.             (let* ((syntax (c-guess-basic-syntax))
  2206.                (len (length syntax))
  2207.                (ic (format "%s" (car (nth (1- len) syntax)))))
  2208.               (if (memq 'v19 c-emacs-features)
  2209.               (cons ic 0)
  2210.             ic))
  2211.             )))
  2212.       (offset (c-read-offset langelem)))
  2213.      (list langelem offset current-prefix-arg)))
  2214.   ;; sanity check offset
  2215.   (or (eq offset '+)
  2216.       (eq offset '-)
  2217.       (eq offset '++)
  2218.       (eq offset '--)
  2219.       (eq offset '*)
  2220.       (eq offset '/)
  2221.       (integerp offset)
  2222.       (fboundp offset)
  2223.       (boundp offset)
  2224.       (error "Offset must be int, func, var, or in [+,-,++,--,*,/]: %s"
  2225.          offset))
  2226.   (let ((entry (assq symbol c-offsets-alist)))
  2227.     (if entry
  2228.     (setcdr entry offset)
  2229.       (if add-p
  2230.       (setq c-offsets-alist (cons (cons symbol offset) c-offsets-alist))
  2231.     (error "%s is not a valid syntactic symbol." symbol))))
  2232.   (c-keep-region-active))
  2233.  
  2234. (defun c-set-style-1 (stylevars)
  2235.   ;; given a style's variable alist, institute the style
  2236.   (mapcar
  2237.    (function
  2238.     (lambda (conscell)
  2239.       (let ((attr (car conscell))
  2240.         (val  (cdr conscell)))
  2241.     ;; KLUDGE ALERT: special case for c-offsets-alist
  2242.     (if (not (eq attr 'c-offsets-alist))
  2243.         (set attr val)
  2244.       (mapcar
  2245.        (function
  2246.         (lambda (langentry)
  2247.           (let ((langelem (car langentry))
  2248.             (offset (cdr langentry)))
  2249.         (c-set-offset langelem offset)
  2250.         )))
  2251.        val))
  2252.     )))
  2253.    stylevars))
  2254.  
  2255. ;;;###autoload
  2256. (defun c-set-style (stylename)
  2257.   "Set cc-mode variables to use one of several different indentation styles.
  2258. STYLENAME is a string representing the desired style from the list of
  2259. styles described in the variable `c-style-alist'.  See that variable
  2260. for details of setting up styles."
  2261.   (interactive (list (let ((completion-ignore-case t)
  2262.                (prompt (format "Which %s indentation style? "
  2263.                        mode-name)))
  2264.                (completing-read prompt c-style-alist nil t))))
  2265.   (let ((vars (cdr (or (assoc (downcase stylename) c-style-alist)
  2266.                ;; backwards compatibility
  2267.                (assoc (upcase stylename) c-style-alist)
  2268.                )))
  2269.     (default (cdr (assoc "cc-mode" c-style-alist))))
  2270.     (or vars (error "Invalid indentation style `%s'" stylename))
  2271.     (or default (error "No `cc-mode' style found!"))
  2272.     ;; first reset the style to `cc-mode' to give every style a common
  2273.     ;; base. Then institute the new style.
  2274.     (c-set-style-1 default)
  2275.     (if (not (string= stylename "cc-mode"))
  2276.     (c-set-style-1 vars)))
  2277.   (c-keep-region-active))
  2278.  
  2279. (defun c-add-style (style descrip &optional set-p)
  2280.   "Adds a style to `c-style-alist', or updates an existing one.
  2281. STYLE is a string identifying the style to add or update.  DESCRIP is
  2282. an association list describing the style and must be of the form:
  2283.  
  2284.   ((VARIABLE . VALUE) [(VARIABLE . VALUE) ...])
  2285.  
  2286. See the variable `c-style-alist' for the semantics of VARIABLE and
  2287. VALUE.  This function also sets the current style to STYLE using
  2288. `c-set-style' if the optional SET-P flag is non-nil."
  2289.   (interactive
  2290.    (let ((stylename (completing-read "Style to add: " c-style-alist))
  2291.      (description (eval-minibuffer "Style description: ")))
  2292.      (list stylename description
  2293.        (y-or-n-p "Set the style too? "))))
  2294.   (setq style (downcase style))
  2295.   (let ((s (assoc style c-style-alist)))
  2296.     (if s
  2297.     (setcdr s (copy-alist descrip))    ; replace
  2298.       (setq c-style-alist (cons (cons style descrip) c-style-alist))))
  2299.   (and set-p (c-set-style style)))
  2300.  
  2301. (defun c-fill-paragraph (&optional arg)
  2302.   "Like \\[fill-paragraph] but handles C and C++ style comments.
  2303. If any of the current line is a comment or within a comment,
  2304. fill the comment or the paragraph of it that point is in,
  2305. preserving the comment indentation or line-starting decorations.
  2306.  
  2307. Optional prefix ARG means justify paragraph as well."
  2308.   (interactive "P")
  2309.   (let* (comment-start-place
  2310.      (first-line
  2311.       ;; Check for obvious entry to comment.
  2312.       (save-excursion
  2313.         (beginning-of-line)
  2314.         (skip-chars-forward " \t\n")
  2315.         (and (looking-at comment-start-skip)
  2316.          (setq comment-start-place (point)))))
  2317.      (re1 (if (memq 'new-re c-emacs-features)
  2318.           "\\|[ \t]*/\\*[ \t]*$\\|[ \t]*\\*/[ \t]*$\\|[ \t/*]*$"
  2319.         "\\|^[ \t]*/\\*[ \t]*$\\|^[ \t]*\\*/[ \t]*$\\|^[ \t/*]*$"))
  2320.      )
  2321.     (if (and c-double-slash-is-comments-p
  2322.          (save-excursion
  2323.            (beginning-of-line)
  2324.            (looking-at ".*//")))
  2325.     (let (fill-prefix
  2326.            ;; Lines containing just a comment start or just an end
  2327.            ;; should not be filled into paragraphs they are next
  2328.            ;; to.
  2329.           (paragraph-start (concat paragraph-start re1))
  2330.           (paragraph-separate (concat paragraph-separate re1)))
  2331.       (save-excursion
  2332.         (beginning-of-line)
  2333.         ;; Move up to first line of this comment.
  2334.         (while (and (not (bobp))
  2335.             (looking-at "[ \t]*//[ \t]*[^ \t\n]"))
  2336.           (forward-line -1))
  2337.         (if (not (looking-at ".*//[ \t]*[^ \t\n]"))
  2338.         (forward-line 1))
  2339.         ;; Find the comment start in this line.
  2340.         (re-search-forward "[ \t]*//[ \t]*")
  2341.         ;; Set the fill-prefix to be what all lines except the first
  2342.         ;; should start with.
  2343.         (setq fill-prefix (buffer-substring (match-beginning 0)
  2344.                         (match-end 0)))
  2345.         (save-restriction
  2346.           ;; Narrow down to just the lines of this comment.
  2347.           (narrow-to-region (c-point 'bol)
  2348.                 (save-excursion
  2349.                   (forward-line 1)
  2350.                   (while (looking-at fill-prefix)
  2351.                     (forward-line 1))
  2352.                   (point)))
  2353.           (fill-paragraph arg)
  2354.           t)))
  2355.       ;; else C style comments
  2356.       (if (or first-line
  2357.           ;; t if we enter a comment between start of function and
  2358.           ;; this line.
  2359.           (eq (c-in-literal) 'c)
  2360.           ;; t if this line contains a comment starter.
  2361.           (setq first-line
  2362.             (save-excursion
  2363.               (beginning-of-line)
  2364.               (prog1
  2365.               (re-search-forward comment-start-skip
  2366.                          (save-excursion (end-of-line)
  2367.                                  (point))
  2368.                          t)
  2369.             (setq comment-start-place (point))))))
  2370.       ;; Inside a comment: fill one comment paragraph.
  2371.       (let ((fill-prefix
  2372.          ;; The prefix for each line of this paragraph
  2373.          ;; is the appropriate part of the start of this line,
  2374.          ;; up to the column at which text should be indented.
  2375.          (save-excursion
  2376.            (beginning-of-line)
  2377.            (if (looking-at "[ \t]*/\\*.*\\*/")
  2378.                (progn (re-search-forward comment-start-skip)
  2379.                   (make-string (current-column) ?\ ))
  2380.              (if first-line (forward-line 1))
  2381.  
  2382.              (let ((line-width (progn (end-of-line) (current-column))))
  2383.                (beginning-of-line)
  2384.                (prog1
  2385.                (buffer-substring
  2386.                 (point)
  2387.  
  2388.                 ;; How shall we decide where the end of the
  2389.                 ;; fill-prefix is?
  2390.                 (progn
  2391.                   (beginning-of-line)
  2392.                   (skip-chars-forward " \t*" (c-point 'eol))
  2393.                   (point)))
  2394.  
  2395.              ;; If the comment is only one line followed
  2396.              ;; by a blank line, calling move-to-column
  2397.              ;; above may have added some spaces and tabs
  2398.              ;; to the end of the line; the fill-paragraph
  2399.              ;; function will then delete it and the
  2400.              ;; newline following it, so we'll lose a
  2401.              ;; blank line when we shouldn't.  So delete
  2402.              ;; anything move-to-column added to the end
  2403.              ;; of the line.  We record the line width
  2404.              ;; instead of the position of the old line
  2405.              ;; end because move-to-column might break a
  2406.              ;; tab into spaces, and the new characters
  2407.              ;; introduced there shouldn't be deleted.
  2408.  
  2409.              ;; If you can see a better way to do this,
  2410.              ;; please make the change.  This seems very
  2411.              ;; messy to me.
  2412.              (delete-region (progn (move-to-column line-width)
  2413.                            (point))
  2414.                     (progn (end-of-line) (point))))))))
  2415.  
  2416.         ;; Lines containing just a comment start or just an end
  2417.         ;; should not be filled into paragraphs they are next
  2418.         ;; to.
  2419.         (paragraph-start (concat paragraph-start re1))
  2420.         (paragraph-separate (concat paragraph-separate re1))
  2421.         (chars-to-delete 0))
  2422.         (save-restriction
  2423.           ;; Don't fill the comment together with the code
  2424.           ;; following it.  So temporarily exclude everything
  2425.           ;; before the comment start, and everything after the
  2426.           ;; line where the comment ends.  If comment-start-place
  2427.           ;; is non-nil, the comment starter is there.  Otherwise,
  2428.           ;; point is inside the comment.
  2429.           (narrow-to-region (save-excursion
  2430.                   (if comment-start-place
  2431.                       (goto-char comment-start-place)
  2432.                     (search-backward "/*"))
  2433.                   ;; Protect text before the comment
  2434.                   ;; start by excluding it.  Add
  2435.                   ;; spaces to bring back proper
  2436.                   ;; indentation of that point.
  2437.                   (let ((column (current-column)))
  2438.                     (prog1 (point)
  2439.                       (setq chars-to-delete column)
  2440.                       (insert-char ?\  column))))
  2441.                 (save-excursion
  2442.                   (if comment-start-place
  2443.                       (goto-char (+ comment-start-place 2)))
  2444.                   (search-forward "*/" nil 'move)
  2445.                   (forward-line 1)
  2446.                   (point)))
  2447.           (fill-paragraph arg)
  2448.           (save-excursion
  2449.         ;; Delete the chars we inserted to avoid clobbering
  2450.         ;; the stuff before the comment start.
  2451.         (goto-char (point-min))
  2452.         (if (> chars-to-delete 0)
  2453.             (delete-region (point) (+ (point) chars-to-delete)))
  2454.         ;; Find the comment ender (should be on last line of
  2455.         ;; buffer, given the narrowing) and don't leave it on
  2456.         ;; its own line, unless that's the style that's desired.
  2457.         (goto-char (point-max))
  2458.         (forward-line -1)
  2459.         (search-forward "*/" nil 'move)
  2460.         (beginning-of-line)
  2461.         (if (and c-hanging-comment-ender-p
  2462.              (looking-at "[ \t]*\\*/"))
  2463.             ;(delete-indentation)))))
  2464.             (let ((fill-column (+ fill-column 9999)))
  2465.               (forward-line -1)
  2466.               (fill-region-as-paragraph (point) (point-max))))))
  2467.         t)))))
  2468.  
  2469. ;; better movement routines for ThisStyleOfVariablesCommonInCPlusPlus
  2470. ;; originally contributed by Terry_Glanfield.Southern@rxuk.xerox.com
  2471. (defun c-forward-into-nomenclature (&optional arg)
  2472.   "Move forward to end of a nomenclature section or word.
  2473. With arg, to it arg times."
  2474.   (interactive "p")
  2475.   (let ((case-fold-search nil))
  2476.     (if (> arg 0)
  2477.     (re-search-forward "\\W*\\([A-Z]*[a-z0-9]*\\)" (point-max) t arg)
  2478.       (while (and (< arg 0)
  2479.           (re-search-backward
  2480.            "\\(\\(\\W\\|[a-z0-9]\\)[A-Z]+\\|\\W\\w+\\)"
  2481.            (point-min) 0))
  2482.     (forward-char 1)
  2483.     (setq arg (1+ arg)))))
  2484.   (c-keep-region-active))
  2485.  
  2486. (defun c-backward-into-nomenclature (&optional arg)
  2487.   "Move backward to beginning of a nomenclature section or word.
  2488. With optional ARG, move that many times.  If ARG is negative, move
  2489. forward."
  2490.   (interactive "p")
  2491.   (c-forward-into-nomenclature (- arg))
  2492.   (c-keep-region-active))
  2493.  
  2494. (defun c-scope-operator ()
  2495.   "Insert a double colon scope operator at point.
  2496. No indentation or other \"electric\" behavior is performed."
  2497.   (interactive)
  2498.   (insert "::"))
  2499.  
  2500.  
  2501. (defun c-beginning-of-statement (&optional count lim sentence-flag)
  2502.   "Go to the beginning of the innermost C statement.
  2503. With prefix arg, go back N - 1 statements.  If already at the
  2504. beginning of a statement then go to the beginning of the preceding
  2505. one.  If within a string or comment, or next to a comment (only
  2506. whitespace between), move by sentences instead of statements.
  2507.  
  2508. When called from a program, this function takes 3 optional args: the
  2509. repetition count, a buffer position limit which is the farthest back
  2510. to search, and a flag saying whether to do sentence motion when in a
  2511. comment."
  2512.   (interactive (list (prefix-numeric-value current-prefix-arg)
  2513.              nil t))
  2514.   (let ((here (point))
  2515.     (count (or count 1))
  2516.     (lim (or lim (c-point 'bod)))
  2517.     state)
  2518.     (save-excursion
  2519.       (goto-char lim)
  2520.       (setq state (parse-partial-sexp (point) here nil nil)))
  2521.     (if (and sentence-flag
  2522.          (or (nth 3 state)
  2523.          (nth 4 state)
  2524.          (looking-at (concat "[ \t]*" comment-start-skip))
  2525.          (save-excursion
  2526.            (skip-chars-backward " \t")
  2527.            (goto-char (- (point) 2))
  2528.            (looking-at "\\*/"))))
  2529.     (forward-sentence (- count))
  2530.       (while (> count 0)
  2531.     (c-beginning-of-statement-1 lim)
  2532.     (setq count (1- count)))
  2533.       (while (< count 0)
  2534.     (c-end-of-statement-1)
  2535.     (setq count (1+ count))))
  2536.     ;; its possible we've been left up-buf of lim
  2537.     (goto-char (max (point) lim))
  2538.     )
  2539.   (c-keep-region-active))
  2540.  
  2541. (defun c-end-of-statement (&optional count lim sentence-flag)
  2542.   "Go to the end of the innermost C statement.
  2543.  
  2544. With prefix arg, go forward N - 1 statements.  Move forward to end of
  2545. the next statement if already at end.  If within a string or comment,
  2546. move by sentences instead of statements.
  2547.  
  2548. When called from a program, this function takes 3 optional args: the
  2549. repetition count, a buffer position limit which is the farthest back
  2550. to search, and a flag saying whether to do sentence motion when in a
  2551. comment."
  2552.   (interactive (list (prefix-numeric-value current-prefix-arg)
  2553.              nil t))
  2554.   (c-beginning-of-statement (- (or count 1)) lim sentence-flag)
  2555.   (c-keep-region-active))
  2556.  
  2557. (defun c-beginning-of-statement-1 (&optional lim)
  2558.   ;; move to the start of the current statement, or the previous
  2559.   ;; statement if already at the beginning of one.
  2560.   (let ((firstp t)
  2561.     (substmt-p t)
  2562.     donep c-in-literal-cache
  2563.     ;; KLUDGE ALERT: maybe-labelp is used to pass information
  2564.     ;; between c-crosses-statement-barrier-p and
  2565.     ;; c-beginning-of-statement-1.  A better way should be
  2566.     ;; implemented.
  2567.     maybe-labelp
  2568.     (last-begin (point)))
  2569.     (while (not donep)
  2570.       ;; stop at beginning of buffer
  2571.       (if (bobp) (setq donep t)
  2572.     ;; go backwards one balanced expression, but be careful of
  2573.     ;; unbalanced paren being reached
  2574.     (if (not (c-safe (progn (backward-sexp 1) t)))
  2575.         (progn
  2576.           (if firstp
  2577.           (backward-up-list 1)
  2578.         (goto-char last-begin))
  2579.           ;; skip over any unary operators, or other special
  2580.           ;; characters appearing at front of identifier
  2581.           (save-excursion
  2582.         (c-backward-syntactic-ws lim)
  2583.         (skip-chars-backward "-+!*&:.~ \t\n")
  2584.         (if (= (preceding-char) ?\()
  2585.             (setq last-begin (point))))
  2586.           (goto-char last-begin)
  2587.           (setq last-begin (point)
  2588.             donep t)))
  2589.  
  2590.     (setq maybe-labelp nil)
  2591.     ;; see if we're in a literal. if not, then this bufpos may be
  2592.     ;; a candidate for stopping
  2593.     (cond
  2594.      ;; CASE 0: did we hit the error condition above?
  2595.      (donep)
  2596.      ;; CASE 1: are we in a literal?
  2597.      ((eq (c-in-literal lim) 'pound)
  2598.       (beginning-of-line))
  2599.      ;; CASE 2: some other kind of literal?
  2600.      ((c-in-literal lim))
  2601.      ;; CASE 3: are we looking at a conditional keyword?
  2602.      ((or (looking-at c-conditional-key)
  2603.           (and (= (following-char) ?\()
  2604.            (save-excursion
  2605.              (forward-sexp 1)
  2606.              (c-forward-syntactic-ws)
  2607.              (/= (following-char) ?\;))
  2608.            (let ((here (point))
  2609.              (foundp (progn
  2610.                    (c-backward-syntactic-ws lim)
  2611.                    (forward-word -1)
  2612.                    (and lim
  2613.                     (<= lim (point))
  2614.                     (not (c-in-literal lim))
  2615.                     (looking-at c-conditional-key)
  2616.                     ))))
  2617.              ;; did we find a conditional?
  2618.              (if (not foundp)
  2619.              (goto-char here))
  2620.              foundp)))
  2621.       ;; are we in the middle of an else-if clause?
  2622.       (if (save-excursion
  2623.         (and (not substmt-p)
  2624.              (c-safe (progn (forward-sexp -1) t))
  2625.              (looking-at "\\<else\\>[ \t\n]+\\<if\\>")
  2626.              (not (c-in-literal lim))))
  2627.           (progn
  2628.         (forward-sexp -1)
  2629.         (c-backward-to-start-of-if lim)))
  2630.       ;; are we sitting at an else clause, that we are not a
  2631.       ;; substatement of?
  2632.       (if (and (not substmt-p)
  2633.            (looking-at "\\<else\\>[^_]"))
  2634.           (c-backward-to-start-of-if lim))
  2635.       ;; are we sitting at the while of a do-while?
  2636.       (if (and (looking-at "\\<while\\>[^_]")
  2637.            (c-backward-to-start-of-do lim))
  2638.           (setq substmt-p nil))
  2639.       (setq last-begin (point)
  2640.         donep substmt-p))
  2641.      ;; CASE 4: are we looking at a label?
  2642.      ((looking-at c-label-key))
  2643.      ;; CASE 5: is this the first time we're checking?
  2644.      (firstp (setq firstp nil
  2645.                substmt-p (not (c-crosses-statement-barrier-p
  2646.                        (point) last-begin))
  2647.                last-begin (point)))
  2648.      ;; CASE 6: have we crossed a statement barrier?
  2649.      ((c-crosses-statement-barrier-p (point) last-begin)
  2650.       (setq donep t))
  2651.      ;; CASE 7: ignore labels
  2652.      ((and maybe-labelp
  2653.            (or (and c-access-key (looking-at c-access-key))
  2654.            ;; with switch labels, we have to go back further
  2655.            ;; to try to pick up the case or default
  2656.            ;; keyword. Potential bogosity alert: we assume
  2657.            ;; `case' or `default' is first thing on line
  2658.            (let ((here (point)))
  2659.              (beginning-of-line)
  2660.              (c-forward-syntactic-ws)
  2661.              (if (looking-at c-switch-label-key)
  2662.              t
  2663.                (goto-char here)
  2664.                nil))
  2665.            (looking-at c-label-key))))
  2666.      ;; CASE 8: ObjC or Java method def
  2667.      ((and c-method-key
  2668.            (setq last-begin (c-in-method-def-p)))
  2669.       (setq donep t))
  2670.      ;; CASE 9: nothing special
  2671.      (t (setq last-begin (point)))
  2672.      )))
  2673.     (goto-char last-begin)
  2674.     ;; we always do want to skip over non-whitespace modifier
  2675.     ;; characters that didn't get skipped above
  2676.     (skip-chars-backward "-+!*&:.~" (c-point 'boi))))
  2677.  
  2678. (defun c-end-of-statement-1 ()
  2679.   (condition-case ()
  2680.       (progn
  2681.     (while (and (not (eobp))
  2682.             (let ((beg (point)))
  2683.               (forward-sexp 1)
  2684.               (let ((end (point)))
  2685.             (save-excursion
  2686.               (goto-char beg)
  2687.               (not (re-search-forward "[;{}]" end t)))))))
  2688.     (re-search-backward "[;}]")
  2689.     (forward-char 1))
  2690.     (error 
  2691.      (let ((beg (point)))
  2692.        (backward-up-list -1)
  2693.        (let ((end (point)))
  2694.      (goto-char beg)
  2695.      (search-forward ";" end 'move))))))
  2696.  
  2697. (defun c-crosses-statement-barrier-p (from to)
  2698.   ;; Does buffer positions FROM to TO cross a C statement boundary?
  2699.   (let ((here (point))
  2700.     (lim from)
  2701.     crossedp)
  2702.     (condition-case ()
  2703.     (progn
  2704.       (goto-char from)
  2705.       (while (and (not crossedp)
  2706.               (< (point) to))
  2707.         (skip-chars-forward "^;{}:" to)
  2708.         (if (not (c-in-literal lim))
  2709.         (progn
  2710.           (if (memq (following-char) '(?\; ?{ ?}))
  2711.               (setq crossedp t)
  2712.             (if (= (following-char) ?:)
  2713.             (setq maybe-labelp t))
  2714.             (forward-char 1))
  2715.           (setq lim (point)))
  2716.           (forward-char 1))))
  2717.       (error (setq crossedp nil)))
  2718.     (goto-char here)
  2719.     crossedp))
  2720.  
  2721.  
  2722. (defun c-up-conditional (count)
  2723.   "Move back to the containing preprocessor conditional, leaving mark behind.
  2724. A prefix argument acts as a repeat count.  With a negative argument,
  2725. move forward to the end of the containing preprocessor conditional.
  2726. When going backwards, `#elif' is treated like `#else' followed by
  2727. `#if'.  When going forwards, `#elif' is ignored."
  2728.   (interactive "p")
  2729.   (c-forward-conditional (- count) t)
  2730.   (c-keep-region-active))
  2731.  
  2732. (defun c-backward-conditional (count &optional up-flag)
  2733.   "Move back across a preprocessor conditional, leaving mark behind.
  2734. A prefix argument acts as a repeat count.  With a negative argument,
  2735. move forward across a preprocessor conditional."
  2736.   (interactive "p")
  2737.   (c-forward-conditional (- count) up-flag)
  2738.   (c-keep-region-active))
  2739.  
  2740. (defun c-forward-conditional (count &optional up-flag)
  2741.   "Move forward across a preprocessor conditional, leaving mark behind.
  2742. A prefix argument acts as a repeat count.  With a negative argument,
  2743. move backward across a preprocessor conditional."
  2744.   (interactive "p")
  2745.   (let* ((forward (> count 0))
  2746.      (increment (if forward -1 1))
  2747.      (search-function (if forward 're-search-forward 're-search-backward))
  2748.      (new))
  2749.     (save-excursion
  2750.       (while (/= count 0)
  2751.     (let ((depth (if up-flag 0 -1)) found)
  2752.       (save-excursion
  2753.         ;; Find the "next" significant line in the proper direction.
  2754.         (while (and (not found)
  2755.             ;; Rather than searching for a # sign that
  2756.             ;; comes at the beginning of a line aside from
  2757.             ;; whitespace, search first for a string
  2758.             ;; starting with # sign.  Then verify what
  2759.             ;; precedes it.  This is faster on account of
  2760.             ;; the fastmap feature of the regexp matcher.
  2761.             (funcall search-function
  2762.                  "#[ \t]*\\(if\\|elif\\|endif\\)"
  2763.                  nil t))
  2764.           (beginning-of-line)
  2765.           ;; Now verify it is really a preproc line.
  2766.           (if (looking-at "^[ \t]*#[ \t]*\\(if\\|elif\\|endif\\)")
  2767.           (let ((prev depth))
  2768.             ;; Update depth according to what we found.
  2769.             (beginning-of-line)
  2770.             (cond ((looking-at "[ \t]*#[ \t]*endif")
  2771.                (setq depth (+ depth increment)))
  2772.               ((looking-at "[ \t]*#[ \t]*elif")
  2773.                (if (and forward (= depth 0))
  2774.                    (setq found (point))))
  2775.               (t (setq depth (- depth increment))))
  2776.             ;; If we are trying to move across, and we find an
  2777.             ;; end before we find a beginning, get an error.
  2778.             (if (and (< prev 0) (< depth prev))
  2779.             (error (if forward
  2780.                    "No following conditional at this level"
  2781.                  "No previous conditional at this level")))
  2782.             ;; When searching forward, start from next line so
  2783.             ;; that we don't find the same line again.
  2784.             (if forward (forward-line 1))
  2785.             ;; If this line exits a level of conditional, exit
  2786.             ;; inner loop.
  2787.             (if (< depth 0)
  2788.             (setq found (point))))
  2789.         ;; else
  2790.         (if forward (forward-line 1))
  2791.         )))
  2792.       (or found
  2793.           (error "No containing preprocessor conditional"))
  2794.       (goto-char (setq new found)))
  2795.     (setq count (+ count increment))))
  2796.     (push-mark)
  2797.     (goto-char new))
  2798.   (c-keep-region-active))
  2799.  
  2800.  
  2801. ;; commands to indent lines, regions, defuns, and expressions
  2802. (defun c-indent-command (&optional whole-exp)
  2803.   "Indent current line as C++ code, or in some cases insert a tab character.
  2804.  
  2805. If `c-tab-always-indent' is t, always just indent the current line.
  2806. If nil, indent the current line only if point is at the left margin or
  2807. in the line's indentation; otherwise insert a tab.  If other than nil
  2808. or t, then tab is inserted only within literals (comments and strings)
  2809. and inside preprocessor directives, but line is always reindented.
  2810.  
  2811. A numeric argument, regardless of its value, means indent rigidly all
  2812. the lines of the expression starting after point so that this line
  2813. becomes properly indented.  The relative indentation among the lines
  2814. of the expression are preserved."
  2815.   (interactive "P")
  2816.   (let ((bod (c-point 'bod)))
  2817.     (if whole-exp
  2818.     ;; If arg, always indent this line as C
  2819.     ;; and shift remaining lines of expression the same amount.
  2820.     (let ((shift-amt (c-indent-line))
  2821.           beg end)
  2822.       (save-excursion
  2823.         (if (eq c-tab-always-indent t)
  2824.         (beginning-of-line))
  2825.         (setq beg (point))
  2826.         (forward-sexp 1)
  2827.         (setq end (point))
  2828.         (goto-char beg)
  2829.         (forward-line 1)
  2830.         (setq beg (point)))
  2831.       (if (> end beg)
  2832.           (indent-code-rigidly beg end (- shift-amt) "#")))
  2833.       ;; No arg supplied, use c-tab-always-indent to determine
  2834.       ;; behavior
  2835.       (cond
  2836.        ;; CASE 1: indent when at column zero or in lines indentation,
  2837.        ;; otherwise insert a tab
  2838.        ((not c-tab-always-indent)
  2839.     (if (save-excursion
  2840.           (skip-chars-backward " \t")
  2841.           (not (bolp)))
  2842.         (insert-tab)
  2843.       (c-indent-line)))
  2844.        ;; CASE 2: just indent the line
  2845.        ((eq c-tab-always-indent t)
  2846.     (c-indent-line))
  2847.        ;; CASE 3: if in a literal, insert a tab, but always indent the
  2848.        ;; line
  2849.        (t
  2850.     (if (c-in-literal bod)
  2851.         (insert-tab))
  2852.     (c-indent-line)
  2853.     )))))
  2854.  
  2855. (defun c-indent-exp (&optional shutup-p)
  2856.   "Indent each line in balanced expression following point.
  2857. Optional SHUTUP-P if non-nil, inhibits message printing and error checking."
  2858.   (interactive "P")
  2859.   (let ((here (point))
  2860.     end progress-p)
  2861.     (unwind-protect
  2862.     (let ((c-echo-syntactic-information-p nil) ;keep quiet for speed
  2863.           (start (progn
  2864.                ;; try to be smarter about finding the range of
  2865.                ;; lines to indent. skip all following
  2866.                ;; whitespace. failing that, try to find any
  2867.                ;; opening brace on the current line
  2868.                (skip-chars-forward " \t\n")
  2869.                (if (memq (following-char) '(?\( ?\[ ?\{))
  2870.                (point)
  2871.              (let ((state (parse-partial-sexp (point)
  2872.                               (c-point 'eol))))
  2873.                (and (nth 1 state)
  2874.                 (goto-char (nth 1 state))
  2875.                 (memq (following-char) '(?\( ?\[ ?\{))
  2876.                 (point)))))))
  2877.       ;; find balanced expression end
  2878.       (setq end (and (c-safe (progn (forward-sexp 1) t))
  2879.              (point-marker)))
  2880.       ;; sanity check
  2881.       (and (not start)
  2882.            (not shutup-p)
  2883.            (error "Cannot find start of balanced expression to indent."))
  2884.       (and (not end)
  2885.            (not shutup-p)
  2886.            (error "Cannot find end of balanced expression to indent."))
  2887.       (c-progress-init start end 'c-indent-exp)
  2888.       (setq progress-p t)
  2889.       (goto-char start)
  2890.       (beginning-of-line)
  2891.       (while (< (point) end)
  2892.         (if (not (looking-at "[ \t]*$"))
  2893.         (c-indent-line))
  2894.         (c-progress-update)
  2895.         (forward-line 1)))
  2896.       ;; make sure marker is deleted
  2897.       (and end
  2898.        (set-marker end nil))
  2899.       (and progress-p
  2900.        (c-progress-fini 'c-indent-exp))
  2901.       (goto-char here))))
  2902.  
  2903. (defun c-indent-defun ()
  2904.   "Re-indents the current top-level function def, struct or class declaration."
  2905.   (interactive)
  2906.   (let ((here (point-marker))
  2907.     (c-echo-syntactic-information-p nil)
  2908.     (brace (c-least-enclosing-brace (c-parse-state))))
  2909.     (if brace
  2910.     (goto-char brace)
  2911.       (beginning-of-defun))
  2912.     ;; if we're sitting at b-o-b, it might be because there was no
  2913.     ;; least enclosing brace and we were sitting on the defun's open
  2914.     ;; brace.
  2915.     (if (and (bobp) (not (= (following-char) ?\{)))
  2916.     (goto-char here))
  2917.     ;; if defun-prompt-regexp is non-nil, b-o-d might not leave us at
  2918.     ;; the open brace. I consider this an Emacs bug.
  2919.     (and (boundp 'defun-prompt-regexp)
  2920.      defun-prompt-regexp
  2921.      (looking-at defun-prompt-regexp)
  2922.      (goto-char (match-end 0)))
  2923.     ;; catch all errors in c-indent-exp so we can 1. give more
  2924.     ;; meaningful error message, and 2. restore point
  2925.     (unwind-protect
  2926.     (c-indent-exp)
  2927.       (goto-char here)
  2928.       (set-marker here nil))))
  2929.  
  2930. (defun c-indent-region (start end)
  2931.   ;; Indent every line whose first char is between START and END inclusive.
  2932.   (save-excursion
  2933.     (goto-char start)
  2934.     ;; Advance to first nonblank line.
  2935.     (skip-chars-forward " \t\n")
  2936.     (beginning-of-line)
  2937.     (let (endmark)
  2938.       (unwind-protect
  2939.       (let ((c-tab-always-indent t)
  2940.         ;; shut up any echo msgs on indiv lines
  2941.         (c-echo-syntactic-information-p nil))
  2942.         (c-progress-init start end 'c-indent-region)
  2943.         (setq endmark (copy-marker end))
  2944.         (while (and (bolp)
  2945.             (not (eobp))
  2946.             (< (point) endmark))
  2947.           ;; update progress
  2948.           (c-progress-update)
  2949.           ;; Indent one line as with TAB.
  2950.           (let (nextline sexpend sexpbeg)
  2951.         ;; skip blank lines
  2952.         (skip-chars-forward " \t\n")
  2953.         (beginning-of-line)
  2954.         ;; indent the current line
  2955.         (c-indent-line)
  2956.         (if (save-excursion
  2957.               (beginning-of-line)
  2958.               (looking-at "[ \t]*#"))
  2959.             (forward-line 1)
  2960.           (save-excursion
  2961.             ;; Find beginning of following line.
  2962.             (setq nextline (c-point 'bonl))
  2963.             ;; Find first beginning-of-sexp for sexp extending past
  2964.             ;; this line.
  2965.             (beginning-of-line)
  2966.             (while (< (point) nextline)
  2967.               (condition-case nil
  2968.               (progn
  2969.                 (forward-sexp 1)
  2970.                 (setq sexpend (point)))
  2971.             (error (setq sexpend nil)
  2972.                    (goto-char nextline)))
  2973.               (c-forward-syntactic-ws))
  2974.             (if sexpend
  2975.             (progn 
  2976.               ;; make sure the sexp we found really starts on the
  2977.               ;; current line and extends past it
  2978.               (goto-char sexpend)
  2979.               (setq sexpend (point-marker))
  2980.               (c-safe (backward-sexp 1))
  2981.               (setq sexpbeg (point)))))
  2982.           ;; check to see if the next line starts a
  2983.           ;; comment-only line
  2984.           (save-excursion
  2985.             (forward-line 1)
  2986.             (skip-chars-forward " \t")
  2987.             (if (looking-at c-comment-start-regexp)
  2988.             (setq sexpbeg (c-point 'bol))))
  2989.           ;; If that sexp ends within the region, indent it all at
  2990.           ;; once, fast.
  2991.           (condition-case nil
  2992.               (if (and sexpend
  2993.                    (> sexpend nextline)
  2994.                    (<= sexpend endmark))
  2995.               (progn
  2996.                 (goto-char sexpbeg)
  2997.                 (c-indent-exp 'shutup)
  2998.                 (c-progress-update)
  2999.                 (goto-char sexpend)))
  3000.             (error
  3001.              (goto-char sexpbeg)
  3002.              (c-indent-line)))
  3003.           ;; Move to following line and try again.
  3004.           (and sexpend
  3005.                (markerp sexpend)
  3006.                (set-marker sexpend nil))
  3007.           (forward-line 1)))))
  3008.     (set-marker endmark nil)
  3009.     (c-progress-fini 'c-indent-region)
  3010.     ))))
  3011.  
  3012. (defun c-mark-function ()
  3013.   "Put mark at end of a C, C++, or Objective-C defun, point at beginning."
  3014.   (interactive)
  3015.   (let ((here (point))
  3016.     ;; there should be a c-point position for 'eod
  3017.     (eod  (save-excursion (end-of-defun) (point)))
  3018.     (state (c-parse-state))
  3019.     brace)
  3020.     (while state
  3021.       (setq brace (car state))
  3022.       (if (consp brace)
  3023.       (goto-char (cdr brace))
  3024.     (goto-char brace))
  3025.       (setq state (cdr state)))
  3026.     (if (= (following-char) ?{)
  3027.     (progn
  3028.       (forward-line -1)
  3029.       (while (not (or (bobp)
  3030.               (looking-at "[ \t]*$")))
  3031.         (forward-line -1)))
  3032.       (forward-line 1)
  3033.       (skip-chars-forward " \t\n"))
  3034.     (push-mark here)
  3035.     (push-mark eod nil t)))
  3036.  
  3037.  
  3038. ;; for progress reporting
  3039. (defvar c-progress-info nil)
  3040.  
  3041. (defun c-progress-init (start end context)
  3042.   ;; start the progress update messages.  if this emacs doesn't have a
  3043.   ;; built-in timer, just be dumb about it
  3044.   (if (not (fboundp 'current-time))
  3045.       (message "indenting region... (this may take a while)")
  3046.     ;; if progress has already been initialized, do nothing. otherwise
  3047.     ;; initialize the counter with a vector of:
  3048.     ;; [start end lastsec context]
  3049.     (if c-progress-info
  3050.     ()
  3051.       (setq c-progress-info (vector start
  3052.                     (save-excursion
  3053.                       (goto-char end)
  3054.                       (point-marker))
  3055.                     (nth 1 (current-time))
  3056.                     context))
  3057.       (message "indenting region..."))))
  3058.  
  3059. (defun c-progress-update ()
  3060.   ;; update progress
  3061.   (if (not (and c-progress-info c-progress-interval))
  3062.       nil
  3063.     (let ((now (nth 1 (current-time)))
  3064.       (start (aref c-progress-info 0))
  3065.       (end (aref c-progress-info 1))
  3066.       (lastsecs (aref c-progress-info 2)))
  3067.       ;; should we update?  currently, update happens every 2 seconds,
  3068.       ;; what's the right value?
  3069.       (if (< c-progress-interval (- now lastsecs))
  3070.       (progn
  3071.         (message "indenting region... (%d%% complete)"
  3072.              (/ (* 100 (- (point) start)) (- end start)))
  3073.         (aset c-progress-info 2 now)))
  3074.       )))
  3075.  
  3076. (defun c-progress-fini (context)
  3077.   ;; finished
  3078.   (if (or (eq context (aref c-progress-info 3))
  3079.       (eq context t))
  3080.       (progn
  3081.     (set-marker (aref c-progress-info 1) nil)
  3082.     (setq c-progress-info nil)
  3083.     (message "indenting region...done"))))
  3084.  
  3085.  
  3086. ;; Skipping of "syntactic whitespace" for Emacs 19.  Syntactic
  3087. ;; whitespace is defined as lexical whitespace, C and C++ style
  3088. ;; comments, and preprocessor directives.  Search no farther back or
  3089. ;; forward than optional LIM.  If LIM is omitted, `beginning-of-defun'
  3090. ;; is used for backward skipping, point-max is used for forward
  3091. ;; skipping.  Note that Emacs 18 support has been moved to cc-mode-18.el.
  3092.  
  3093. (defun c-forward-syntactic-ws (&optional lim)
  3094.   ;; Forward skip of syntactic whitespace for Emacs 19.
  3095.   (save-restriction
  3096.     (let* ((lim (or lim (point-max)))
  3097.        (here lim)
  3098.        (hugenum (point-max)))
  3099.       (narrow-to-region lim (point))
  3100.       (while (/= here (point))
  3101.     (setq here (point))
  3102.     (forward-comment hugenum)
  3103.     ;; skip preprocessor directives
  3104.     (if (and (= (following-char) ?#)
  3105.          (= (c-point 'boi) (point)))
  3106.         (end-of-line)
  3107.       )))))
  3108.  
  3109. (defun c-backward-syntactic-ws (&optional lim)
  3110.   ;; Backward skip over syntactic whitespace for Emacs 19.
  3111.   (save-restriction
  3112.     (let* ((lim (or lim (c-point 'bod)))
  3113.        (here lim)
  3114.        (hugenum (- (point-max))))
  3115.       (if (< lim (point))
  3116.       (progn
  3117.         (narrow-to-region lim (point))
  3118.         (while (/= here (point))
  3119.           (setq here (point))
  3120.           (forward-comment hugenum)
  3121.           (if (eq (c-in-literal lim) 'pound)
  3122.           (beginning-of-line))
  3123.           )))
  3124.       )))
  3125.  
  3126.  
  3127. ;; Return `c' if in a C-style comment, `c++' if in a C++ style
  3128. ;; comment, `string' if in a string literal, `pound' if on a
  3129. ;; preprocessor line, or nil if not in a comment at all.  Optional LIM
  3130. ;; is used as the backward limit of the search.  If omitted, or nil,
  3131. ;; `beginning-of-defun' is used."
  3132.  
  3133. ;; This is for all v19 Emacsen supporting either 1-bit or 8-bit syntax
  3134. (defun c-in-literal (&optional lim)
  3135.   ;; Determine if point is in a C++ literal. we cache the last point
  3136.   ;; calculated if the cache is enabled
  3137.   (if (and (boundp 'c-in-literal-cache)
  3138.        c-in-literal-cache
  3139.        (= (point) (aref c-in-literal-cache 0)))
  3140.       (aref c-in-literal-cache 1)
  3141.     (let ((rtn (save-excursion
  3142.          (let* ((lim (or lim (c-point 'bod)))
  3143.             (here (point))
  3144.             (state (parse-partial-sexp lim (point))))
  3145.            (cond
  3146.             ((nth 3 state) 'string)
  3147.             ((nth 4 state) (if (nth 7 state) 'c++ 'c))
  3148.             ((progn
  3149.                (goto-char here)
  3150.                (beginning-of-line)
  3151.                (looking-at "[ \t]*#"))
  3152.              'pound)
  3153.             (t nil))))))
  3154.       ;; cache this result if the cache is enabled
  3155.       (and (boundp 'c-in-literal-cache)
  3156.        (setq c-in-literal-cache (vector (point) rtn)))
  3157.       rtn)))
  3158.  
  3159.  
  3160. ;; utilities for moving and querying around syntactic elements
  3161. (defun c-parse-state ()
  3162.   ;; Finds and records all open parens between some important point
  3163.   ;; earlier in the file and point.
  3164.   ;;
  3165.   ;; if there's a state cache, return it
  3166.   (if (boundp 'c-state-cache) c-state-cache
  3167.     (let* (at-bob
  3168.        (pos (save-excursion
  3169.           ;; go back 2 bods, but ignore any bogus positions
  3170.           ;; returned by beginning-of-defun (i.e. open paren
  3171.           ;; in column zero)
  3172.           (let ((cnt 2))
  3173.             (while (not (or at-bob (zerop cnt)))
  3174.               (beginning-of-defun)
  3175.               (if (= (following-char) ?\{)
  3176.               (setq cnt (1- cnt)))
  3177.               (if (bobp)
  3178.               (setq at-bob t))))
  3179.           (point)))
  3180.        (here (save-excursion
  3181.            ;;(skip-chars-forward " \t}")
  3182.            (point)))
  3183.        (last-bod pos) (last-pos pos)
  3184.        placeholder state sexp-end)
  3185.       ;; cache last bod position
  3186.       (while (catch 'backup-bod
  3187.            (setq state nil)
  3188.            (while (and pos (< pos here))
  3189.          (setq last-pos pos)
  3190.          (if (and (setq pos (c-safe (scan-lists pos 1 -1)))
  3191.               (<= pos here))
  3192.              (progn
  3193.                (setq sexp-end (c-safe (scan-sexps (1- pos) 1)))
  3194.                (if (and sexp-end
  3195.                 (<= sexp-end here))
  3196.                ;; we want to record both the start and end
  3197.                ;; of this sexp, but we only want to record
  3198.                ;; the last-most of any of them before here
  3199.                (progn
  3200.                  (if (= (char-after (1- pos)) ?\{)
  3201.                  (setq state (cons (cons (1- pos) sexp-end)
  3202.                            (if (consp (car state))
  3203.                                (cdr state)
  3204.                              state))))
  3205.                  (setq pos sexp-end))
  3206.              ;; we're contained in this sexp so put pos on
  3207.              ;; front of list
  3208.              (setq state (cons (1- pos) state))))
  3209.            ;; something bad happened. check to see if we
  3210.            ;; crossed an unbalanced close brace. if so, we
  3211.            ;; didn't really find the right `important bufpos'
  3212.            ;; so lets back up and try again
  3213.            (if (and (not pos) (not at-bob)
  3214.                 (setq placeholder
  3215.                   (c-safe (scan-lists last-pos 1 1)))
  3216.                 ;;(char-after (1- placeholder))
  3217.                 (<= placeholder here)
  3218.                 (= (char-after (1- placeholder)) ?\}))
  3219.                (while t
  3220.              (setq last-bod (c-safe (scan-lists last-bod -1 1)))
  3221.              (if (not last-bod)
  3222.                  (error "unbalanced close brace at position %d"
  3223.                     (1- placeholder))
  3224.                (setq at-bob (= last-bod (point-min))
  3225.                  pos last-bod)
  3226.                (if (= (char-after last-bod) ?\{)
  3227.                    (throw 'backup-bod t)))
  3228.              ))        ;end-if
  3229.            ))            ;end-while
  3230.            nil))
  3231.       state)))
  3232.  
  3233. (defun c-whack-state (bufpos state)
  3234.   ;; whack off any state information that appears on STATE which lies
  3235.   ;; after the bounds of BUFPOS.
  3236.   (let (newstate car)
  3237.     (while state
  3238.       (setq car (car state)
  3239.         state (cdr state))
  3240.       (if (consp car)
  3241.       ;; just check the car, because in a balanced brace
  3242.       ;; expression, it must be impossible for the corresponding
  3243.       ;; close brace to be before point, but the open brace to be
  3244.       ;; after.
  3245.       (if (<= bufpos (car car))
  3246.           nil            ; whack it off
  3247.         ;; its possible that the open brace is before bufpos, but
  3248.         ;; the close brace is after.  In that case, convert this
  3249.         ;; to a non-cons element.
  3250.         (if (<= bufpos (cdr car))
  3251.         (setq newstate (append newstate (list (car car))))
  3252.           ;; we know that both the open and close braces are
  3253.           ;; before bufpos, so we also know that everything else
  3254.           ;; on state is before bufpos, so we can glom up the
  3255.           ;; whole thing and exit.
  3256.           (setq newstate (append newstate (list car) state)
  3257.             state nil)))
  3258.     (if (<= bufpos car)
  3259.         nil                ; whack it off
  3260.       ;; it's before bufpos, so everything else should too
  3261.       (setq newstate (append newstate (list car) state)
  3262.         state nil))))
  3263.     newstate))
  3264.  
  3265. (defun c-hack-state (bufpos which state)
  3266.   ;; Using BUFPOS buffer position, and WHICH (must be 'open or
  3267.   ;; 'close), hack the c-parse-state STATE and return the results.
  3268.   (if (eq which 'open)
  3269.       (let ((car (car state)))
  3270.     (if (or (null car)
  3271.         (consp car)
  3272.         (/= bufpos car))
  3273.         (cons bufpos state)
  3274.       state))
  3275.     (if (not (eq which 'close))
  3276.     (error "c-hack-state, bad argument: %s" which))
  3277.     ;; 'close brace
  3278.     (let ((car (car state))
  3279.       (cdr (cdr state)))
  3280.       (if (consp car)
  3281.       (setq car (car cdr)
  3282.         cdr (cdr cdr)))
  3283.       ;; TBD: is this test relevant???
  3284.       (if (consp car)
  3285.       state                ;on error, don't change
  3286.     ;; watch out for balanced expr already on cdr of list
  3287.     (cons (cons car bufpos)
  3288.           (if (consp (car cdr))
  3289.           (cdr cdr) cdr))
  3290.     ))))
  3291.  
  3292. (defun c-adjust-state (from to shift state)
  3293.   ;; Adjust all points in state that lie in the region FROM..TO by
  3294.   ;; SHIFT amount (as would be returned by c-indent-line).
  3295.   (mapcar
  3296.    (function
  3297.     (lambda (e)
  3298.       (if (consp e)
  3299.       (let ((car (car e))
  3300.         (cdr (cdr e)))
  3301.         (if (and (<= from car) (< car to))
  3302.         (setcar e (+ shift car)))
  3303.         (if (and (<= from cdr) (< cdr to))
  3304.         (setcdr e (+ shift cdr))))
  3305.     (if (and (<= from e) (< e to))
  3306.         (setq e (+ shift e))))
  3307.       e))
  3308.    state))
  3309.  
  3310.  
  3311. (defun c-beginning-of-inheritance-list (&optional lim)
  3312.   ;; Go to the first non-whitespace after the colon that starts a
  3313.   ;; multiple inheritance introduction.  Optional LIM is the farthest
  3314.   ;; back we should search.
  3315.   (let ((lim (or lim (c-point 'bod)))
  3316.     (placeholder (progn
  3317.                (back-to-indentation)
  3318.                (point))))
  3319.     (c-backward-syntactic-ws lim)
  3320.     (while (and (> (point) lim)
  3321.         (memq (preceding-char) '(?, ?:))
  3322.         (progn
  3323.           (beginning-of-line)
  3324.           (setq placeholder (point))
  3325.           (skip-chars-forward " \t")
  3326.           (not (looking-at c-class-key))
  3327.           ))
  3328.       (c-backward-syntactic-ws lim))
  3329.     (goto-char placeholder)
  3330.     (skip-chars-forward "^:" (c-point 'eol))))
  3331.  
  3332. (defun c-beginning-of-macro (&optional lim)
  3333.   ;; Go to the beginning of the macro. Right now we don't support
  3334.   ;; multi-line macros too well
  3335.   (back-to-indentation))
  3336.  
  3337. (defun c-in-method-def-p ()
  3338.   ;; Return nil if we aren't in a method definition, otherwise the
  3339.   ;; position of the initial [+-].
  3340.   (save-excursion
  3341.     (beginning-of-line)
  3342.     (and c-method-key
  3343.      (looking-at c-method-key)
  3344.      (point))
  3345.     ))
  3346.  
  3347. (defun c-just-after-func-arglist-p (&optional containing)
  3348.   ;; Return t if we are between a function's argument list closing
  3349.   ;; paren and its opening brace.  Note that the list close brace
  3350.   ;; could be followed by a "const" specifier or a member init hanging
  3351.   ;; colon.  Optional CONTAINING is position of containing s-exp open
  3352.   ;; brace.  If not supplied, point is used as search start.
  3353.   (save-excursion
  3354.     (c-backward-syntactic-ws)
  3355.     (let ((checkpoint (or containing (point))))
  3356.       (goto-char checkpoint)
  3357.       ;; could be looking at const specifier
  3358.       (if (and (= (preceding-char) ?t)
  3359.            (forward-word -1)
  3360.            (looking-at "\\<const\\>"))
  3361.       (c-backward-syntactic-ws)
  3362.     ;; otherwise, we could be looking at a hanging member init
  3363.     ;; colon
  3364.     (goto-char checkpoint)
  3365.     (if (and (= (preceding-char) ?:)
  3366.          (progn
  3367.            (forward-char -1)
  3368.            (c-backward-syntactic-ws)
  3369.            (looking-at "[ \t\n]*:\\([^:]+\\|$\\)")))
  3370.         nil
  3371.       (goto-char checkpoint))
  3372.     )
  3373.       (and (= (preceding-char) ?\))
  3374.        ;; check if we are looking at a method def
  3375.        (or (not c-method-key)
  3376.            (progn
  3377.          (forward-sexp -1)
  3378.          (forward-char -1)
  3379.          (c-backward-syntactic-ws)
  3380.          (not (or (= (preceding-char) ?-)
  3381.               (= (preceding-char) ?+)
  3382.               ;; or a class category
  3383.               (progn
  3384.                 (forward-sexp -2)
  3385.                 (looking-at c-class-key))
  3386.               )))))
  3387.       )))
  3388.  
  3389. ;; defuns to look backwards for things
  3390. (defun c-backward-to-start-of-do (&optional lim)
  3391.   ;; Move to the start of the last "unbalanced" do expression.
  3392.   ;; Optional LIM is the farthest back to search.  If none is found,
  3393.   ;; nil is returned and point is left unchanged, otherwise t is returned.
  3394.   (let ((do-level 1)
  3395.     (case-fold-search nil)
  3396.     (lim (or lim (c-point 'bod)))
  3397.     (here (point))
  3398.     foundp)
  3399.     (while (not (zerop do-level))
  3400.       ;; we protect this call because trying to execute this when the
  3401.       ;; while is not associated with a do will throw an error
  3402.       (condition-case nil
  3403.       (progn
  3404.         (backward-sexp 1)
  3405.         (cond
  3406.          ((memq (c-in-literal lim) '(c c++)))
  3407.          ((looking-at "while\\b[^_]")
  3408.           (setq do-level (1+ do-level)))
  3409.          ((looking-at "do\\b[^_]")
  3410.           (if (zerop (setq do-level (1- do-level)))
  3411.           (setq foundp t)))
  3412.          ((<= (point) lim)
  3413.           (setq do-level 0)
  3414.           (goto-char lim))))
  3415.     (error
  3416.      (goto-char lim)
  3417.      (setq do-level 0))))
  3418.     (if (not foundp)
  3419.     (goto-char here))
  3420.     foundp))
  3421.  
  3422. (defun c-backward-to-start-of-if (&optional lim)
  3423.   ;; Move to the start of the last "unbalanced" if and return t.  If
  3424.   ;; none is found, and we are looking at an if clause, nil is
  3425.   ;; returned.  If none is found and we are looking at an else clause,
  3426.   ;; an error is thrown.
  3427.   (let ((if-level 1)
  3428.     (here (c-point 'bol))
  3429.     (case-fold-search nil)
  3430.     (lim (or lim (c-point 'bod)))
  3431.     (at-if (looking-at "if\\b[^_]")))
  3432.     (catch 'orphan-if
  3433.       (while (and (not (bobp))
  3434.           (not (zerop if-level)))
  3435.     (c-backward-syntactic-ws)
  3436.     (condition-case nil
  3437.         (backward-sexp 1)
  3438.       (error
  3439.        (if at-if
  3440.            (throw 'orphan-if nil)
  3441.          (error "No matching `if' found for `else' on line %d."
  3442.             (1+ (count-lines 1 here))))))
  3443.     (cond
  3444.      ((looking-at "else\\b[^_]")
  3445.       (setq if-level (1+ if-level)))
  3446.      ((looking-at "if\\b[^_]")
  3447.       ;; check for else if... skip over
  3448.       (let ((here (point)))
  3449.         (c-safe (forward-sexp -1))
  3450.         (if (looking-at "\\<else\\>[ \t]+\\<if\\>")
  3451.         nil
  3452.           (setq if-level (1- if-level))
  3453.           (goto-char here))))
  3454.      ((< (point) lim)
  3455.       (setq if-level 0)
  3456.       (goto-char lim))
  3457.      ))
  3458.       t)))
  3459.  
  3460. (defun c-skip-conditional ()
  3461.   ;; skip forward over conditional at point, including any predicate
  3462.   ;; statements in parentheses. No error checking is performed.
  3463.   (forward-sexp
  3464.    ;; else if()
  3465.    (if (looking-at "\\<else\\>[ \t]+\\<if\\>")
  3466.        3
  3467.      ;; do and else aren't followed by parens
  3468.      (if (looking-at "\\<\\(do\\|else\\)\\>")
  3469.      1 2))))
  3470.  
  3471. (defun c-skip-case-statement-forward (state &optional lim)
  3472.   ;; skip forward over case/default bodies, with optional maximal
  3473.   ;; limit. if no next case body is found, nil is returned and point
  3474.   ;; is not moved
  3475.   (let ((lim (or lim (point-max)))
  3476.     (here (point))
  3477.     donep foundp bufpos
  3478.     (safepos (point))
  3479.     (balanced (car state)))
  3480.     ;; search until we've passed the limit, or we've found our match
  3481.     (while (and (< (point) lim)
  3482.         (not donep))
  3483.       (setq safepos (point))
  3484.       ;; see if we can find a case statement, not in a literal
  3485.       (if (and (re-search-forward c-switch-label-key lim 'move)
  3486.            (setq bufpos (match-beginning 0))
  3487.            (not (c-in-literal safepos))
  3488.            (/= bufpos here))
  3489.       ;; if we crossed into a balanced sexp, we know the case is
  3490.       ;; not part of our switch statement, so just bound over the
  3491.       ;; sexp and keep looking.
  3492.       (if (and (consp balanced)
  3493.            (> bufpos (car balanced))
  3494.            (< bufpos (cdr balanced)))
  3495.           (goto-char (cdr balanced))
  3496.         (goto-char bufpos)
  3497.         (setq donep t
  3498.           foundp t))))
  3499.     (if (not foundp)
  3500.     (goto-char here))
  3501.     foundp))
  3502.  
  3503. (defun c-search-uplist-for-classkey (brace-state)
  3504.   ;; search for the containing class, returning a 2 element vector if
  3505.   ;; found. aref 0 contains the bufpos of the class key, and aref 1
  3506.   ;; contains the bufpos of the open brace.
  3507.   (if (null brace-state)
  3508.       ;; no brace-state means we cannot be inside a class
  3509.       nil
  3510.     (let ((carcache (car brace-state))
  3511.       search-start search-end)
  3512.       (if (consp carcache)
  3513.       ;; a cons cell in the first element means that there is some
  3514.       ;; balanced sexp before the current bufpos. this we can
  3515.       ;; ignore. the nth 1 and nth 2 elements define for us the
  3516.       ;; search boundaries
  3517.       (setq search-start (nth 2 brace-state)
  3518.         search-end (nth 1 brace-state))
  3519.     ;; if the car was not a cons cell then nth 0 and nth 1 define
  3520.     ;; for us the search boundaries
  3521.     (setq search-start (nth 1 brace-state)
  3522.           search-end (nth 0 brace-state)))
  3523.       ;; search-end cannot be a cons cell
  3524.       (and (consp search-end)
  3525.        (error "consp search-end: %s" search-end))
  3526.       ;; if search-end is nil, or if the search-end character isn't an
  3527.       ;; open brace, we are definitely not in a class
  3528.       (if (or (not search-end)
  3529.           (< search-end (point-min))
  3530.           (/= (char-after search-end) ?{))
  3531.       nil
  3532.     ;; now, we need to look more closely at search-start.  if
  3533.     ;; search-start is nil, then our start boundary is really
  3534.     ;; point-min.
  3535.     (if (not search-start)
  3536.         (setq search-start (point-min))
  3537.       ;; if search-start is a cons cell, then we can start
  3538.       ;; searching from the end of the balanced sexp just ahead of
  3539.       ;; us
  3540.       (if (consp search-start)
  3541.           (setq search-start (cdr search-start))))
  3542.     ;; now we can do a quick regexp search from search-start to
  3543.     ;; search-end and see if we can find a class key.  watch for
  3544.     ;; class like strings in literals
  3545.     (save-excursion
  3546.       (save-restriction
  3547.         (goto-char search-start)
  3548.         (let (foundp class match-end)
  3549.           (while (and (not foundp)
  3550.               (progn
  3551.                 (c-forward-syntactic-ws)
  3552.                 (> search-end (point)))
  3553.               (re-search-forward c-class-key search-end t))
  3554.         (setq class (match-beginning 0)
  3555.               match-end (match-end 0))
  3556.         (if (c-in-literal search-start)
  3557.             nil            ; its in a comment or string, ignore
  3558.           (goto-char class)
  3559.           (skip-chars-forward " \t\n")
  3560.           (setq foundp (vector (c-point 'boi) search-end))
  3561.           (cond
  3562.            ;; check for embedded keywords
  3563.            ((let ((char (char-after (1- class))))
  3564.               (and char
  3565.                (memq (char-syntax char) '(?w ?_))))
  3566.             (goto-char match-end)
  3567.             (setq foundp nil))
  3568.            ;; make sure we're really looking at the start of a
  3569.            ;; class definition, and not a forward decl, return
  3570.            ;; arg, template arg list, or an ObjC or Java method.
  3571.            ((and c-method-key
  3572.              (re-search-forward c-method-key search-end t))
  3573.             (setq foundp nil))
  3574.            ;; Its impossible to define a regexp for this, and
  3575.            ;; nearly so to do it programmatically.
  3576.            ;;
  3577.            ;; ; picks up forward decls
  3578.            ;; = picks up init lists
  3579.            ;; ) picks up return types
  3580.            ;; > picks up templates, but remember that we can
  3581.            ;;   inherit from templates!
  3582.            ((let ((skipchars "^;=)"))
  3583.               ;; try to see if we found the `class' keyword
  3584.               ;; inside a template arg list
  3585.               (save-excursion
  3586.             (skip-chars-backward "^<>" search-start)
  3587.             (if (= (preceding-char) ?<)
  3588.                 (setq skipchars (concat skipchars ">"))))
  3589.               (skip-chars-forward skipchars search-end)
  3590.               (/= (point) search-end))
  3591.             (setq foundp nil))
  3592.            )))
  3593.           foundp))
  3594.       )))))
  3595.  
  3596. (defun c-inside-bracelist-p (containing-sexp brace-state)
  3597.   ;; return the buffer position of the beginning of the brace list
  3598.   ;; statement if we're inside a brace list, otherwise return nil.
  3599.   ;; CONTAINING-SEXP is the buffer pos of the innermost containing
  3600.   ;; paren. BRACE-STATE is the remainder of the state of enclosing braces
  3601.   ;;
  3602.   ;; N.B.: This algorithm can potentially get confused by cpp macros
  3603.   ;; places in inconvenient locations.  Its a trade-off we make for
  3604.   ;; speed.
  3605.   (or
  3606.    ;; this will pick up enum lists
  3607.    (condition-case ()
  3608.        (save-excursion
  3609.      (goto-char containing-sexp)
  3610.      (forward-sexp -1)
  3611.      (if (or (looking-at "enum[\t\n ]+")
  3612.          (progn (forward-sexp -1)
  3613.             (looking-at "enum[\t\n ]+")))
  3614.          (point)))
  3615.      (error nil))
  3616.    ;; this will pick up array/aggregate init lists, even if they are nested.
  3617.    (save-excursion
  3618.      (let (bufpos failedp)
  3619.        (while (and (not bufpos)
  3620.            containing-sexp)
  3621.      (if (consp containing-sexp)
  3622.          (setq containing-sexp (car brace-state)
  3623.            brace-state (cdr brace-state))
  3624.        ;; see if significant character just before brace is an equal
  3625.        (goto-char containing-sexp)
  3626.        (setq failedp nil)
  3627.        (condition-case ()
  3628.            (progn
  3629.          (forward-sexp -1)
  3630.          (forward-sexp 1)
  3631.          (c-forward-syntactic-ws containing-sexp))
  3632.          (error (setq failedp t)))
  3633.        (if (or failedp (/= (following-char) ?=))
  3634.            ;; lets see if we're nested. find the most nested
  3635.            ;; containing brace
  3636.            (setq containing-sexp (car brace-state)
  3637.              brace-state (cdr brace-state))
  3638.          ;; we've hit the beginning of the aggregate list
  3639.          (c-beginning-of-statement-1 (c-most-enclosing-brace brace-state))
  3640.          (setq bufpos (point)))
  3641.        ))
  3642.        bufpos))
  3643.    ))
  3644.  
  3645.  
  3646. ;; defuns for calculating the syntactic state and indenting a single
  3647. ;; line of C/C++/ObjC code
  3648. (defmacro c-add-syntax (symbol &optional relpos)
  3649.   ;; a simple macro to append the syntax in symbol to the syntax list.
  3650.   ;; try to increase performance by using this macro
  3651.   (` (setq syntax (cons (cons (, symbol) (, relpos)) syntax))))
  3652.  
  3653. (defun c-most-enclosing-brace (state)
  3654.   ;; return the bufpos of the most enclosing brace that hasn't been
  3655.   ;; narrowed out by any enclosing class, or nil if none was found
  3656.   (let (enclosingp)
  3657.     (while (and state (not enclosingp))
  3658.       (setq enclosingp (car state)
  3659.         state (cdr state))
  3660.       (if (consp enclosingp)
  3661.       (setq enclosingp nil)
  3662.     (if (> (point-min) enclosingp)
  3663.         (setq enclosingp nil))
  3664.     (setq state nil)))
  3665.     enclosingp))
  3666.  
  3667. (defun c-least-enclosing-brace (state)
  3668.   ;; return the bufpos of the least (highest) enclosing brace that
  3669.   ;; hasn't been narrowed out by any enclosing class, or nil if none
  3670.   ;; was found.
  3671.   (c-most-enclosing-brace (nreverse state)))
  3672.  
  3673. (defun c-safe-position (bufpos state)
  3674.   ;; return the closest known safe position higher up than point
  3675.   (let ((safepos nil))
  3676.     (while state
  3677.       (setq safepos
  3678.         (if (consp (car state))
  3679.         (cdr (car state))
  3680.           (car state)))
  3681.       (if (< safepos bufpos)
  3682.       (setq state nil)
  3683.     (setq state (cdr state))))
  3684.     safepos))
  3685.  
  3686. (defun c-narrow-out-enclosing-class (state lim)
  3687.   ;; narrow the buffer so that the enclosing class is hidden
  3688.   (let (inclass-p)
  3689.     (and state
  3690.      (setq inclass-p (c-search-uplist-for-classkey state))
  3691.      (narrow-to-region
  3692.       (progn
  3693.         (goto-char (1+ (aref inclass-p 1)))
  3694.         (skip-chars-forward " \t\n" lim)
  3695.         ;; if point is now left of the class opening brace, we're
  3696.         ;; hosed, so try a different tact
  3697.         (if (<= (point) (aref inclass-p 1))
  3698.         (progn
  3699.           (goto-char (1+ (aref inclass-p 1)))
  3700.           (c-forward-syntactic-ws lim)))
  3701.         (point))
  3702.       ;; end point is the end of the current line
  3703.       (progn
  3704.         (goto-char lim)
  3705.         (c-point 'eol))))
  3706.     ;; return the class vector
  3707.     inclass-p))
  3708.  
  3709. (defun c-guess-basic-syntax ()
  3710.   ;; guess the syntactic description of the current line of C++ code.
  3711.   (save-excursion
  3712.     (save-restriction
  3713.       (beginning-of-line)
  3714.       (let* ((indent-point (point))
  3715.          (case-fold-search nil)
  3716.          (fullstate (c-parse-state))
  3717.          (state fullstate)
  3718.          (in-method-intro-p (and c-method-key
  3719.                      (looking-at c-method-key)))
  3720.          literal containing-sexp char-before-ip char-after-ip lim
  3721.          syntax placeholder c-in-literal-cache inswitch-p
  3722.          ;; narrow out any enclosing class
  3723.          (inclass-p (c-narrow-out-enclosing-class state indent-point))
  3724.          )
  3725.  
  3726.     ;; get the buffer position of the most nested opening brace,
  3727.     ;; if there is one, and it hasn't been narrowed out
  3728.     (save-excursion
  3729.       (goto-char indent-point)
  3730.       (skip-chars-forward " \t}")
  3731.       (skip-chars-backward " \t")
  3732.       (while (and state
  3733.               (not in-method-intro-p)
  3734.               (not containing-sexp))
  3735.         (setq containing-sexp (car state)
  3736.           state (cdr state))
  3737.         (if (consp containing-sexp)
  3738.         ;; if cdr == point, then containing sexp is the brace
  3739.         ;; that opens the sexp we close
  3740.         (if (= (cdr containing-sexp) (point))
  3741.             (setq containing-sexp (car containing-sexp))
  3742.           ;; otherwise, ignore this element
  3743.           (setq containing-sexp nil))
  3744.           ;; ignore the bufpos if its been narrowed out by the
  3745.           ;; containing class
  3746.           (if (<= containing-sexp (point-min))
  3747.           (setq containing-sexp nil)))))
  3748.  
  3749.     ;; set the limit on the farthest back we need to search
  3750.     (setq lim (or containing-sexp
  3751.               (if (consp (car fullstate))
  3752.               (cdr (car fullstate))
  3753.             nil)
  3754.               (point-min)))
  3755.  
  3756.     ;; cache char before and after indent point, and move point to
  3757.     ;; the most likely position to perform the majority of tests
  3758.     (goto-char indent-point)
  3759.     (skip-chars-forward " \t")
  3760.     (setq char-after-ip (following-char))
  3761.     (c-backward-syntactic-ws lim)
  3762.     (setq char-before-ip (preceding-char))
  3763.     (goto-char indent-point)
  3764.     (skip-chars-forward " \t")
  3765.  
  3766.     ;; are we in a literal?
  3767.     (setq literal (c-in-literal lim))
  3768.  
  3769.     ;; now figure out syntactic qualities of the current line
  3770.     (cond
  3771.      ;; CASE 1: in a string.
  3772.      ((memq literal '(string))
  3773.       (c-add-syntax 'string (c-point 'bopl)))
  3774.      ;; CASE 2: in a C or C++ style comment.
  3775.      ((memq literal '(c c++))
  3776.       ;; we need to catch multi-paragraph C comments
  3777.       (while (and (zerop (forward-line -1))
  3778.               (looking-at "^[ \t]*$")))
  3779.       (c-add-syntax literal (c-point 'bol)))
  3780.      ;; CASE 3: in a cpp preprocessor
  3781.      ((eq literal 'pound)
  3782.       (c-beginning-of-macro lim)
  3783.       (c-add-syntax 'cpp-macro (c-point 'boi)))
  3784.      ;; CASE 4: in an objective-c method intro
  3785.      (in-method-intro-p
  3786.       (c-add-syntax 'objc-method-intro (c-point 'boi)))
  3787.      ;; CASE 5: Line is at top level.
  3788.      ((null containing-sexp)
  3789.       (cond
  3790.        ;; CASE 5A: we are looking at a defun, class, or
  3791.        ;; inline-inclass method opening brace
  3792.        ((= char-after-ip ?{)
  3793.         (cond
  3794.          ;; CASE 5A.1: we are looking at a class opening brace
  3795.          ((save-excursion
  3796.         (goto-char indent-point)
  3797.         (skip-chars-forward " \t{")
  3798.         ;; TBD: watch out! there could be a bogus
  3799.         ;; c-state-cache in place when we get here.  we have
  3800.         ;; to go through much chicanery to ignore the cache.
  3801.         ;; But of course, there may not be!  BLECH!  BOGUS!
  3802.         (let ((decl
  3803.                (if (boundp 'c-state-cache)
  3804.                (let ((old-cache c-state-cache))
  3805.                  (prog2
  3806.                  (makunbound 'c-state-cache)
  3807.                  (c-search-uplist-for-classkey (c-parse-state))
  3808.                    (setq c-state-cache old-cache)))
  3809.              (c-search-uplist-for-classkey (c-parse-state))
  3810.              )))
  3811.           (and decl
  3812.                (setq placeholder (aref decl 0)))
  3813.           ))
  3814.           (c-add-syntax 'class-open placeholder))
  3815.          ;; CASE 5A.2: brace list open
  3816.          ((save-excursion
  3817.         (c-beginning-of-statement-1 lim)
  3818.         ;; c-b-o-s could have left us at point-min
  3819.         (and (bobp)
  3820.              (c-forward-syntactic-ws indent-point))
  3821.         (setq placeholder (point))
  3822.         (and (or (looking-at "enum[ \t\n]+")
  3823.              (= char-before-ip ?=))
  3824.              (save-excursion
  3825.                (skip-chars-forward "^;(" indent-point)
  3826.                (not (memq (following-char) '(?\; ?\()))
  3827.                )))
  3828.           (c-add-syntax 'brace-list-open placeholder))
  3829.          ;; CASE 5A.3: inline defun open
  3830.          (inclass-p
  3831.           (c-add-syntax 'inline-open (aref inclass-p 0)))
  3832.          ;; CASE 5A.4: ordinary defun open
  3833.          (t
  3834.           (goto-char placeholder)
  3835.           (c-add-syntax 'defun-open (c-point 'bol))
  3836.           )))
  3837.        ;; CASE 5B: first K&R arg decl or member init
  3838.        ((c-just-after-func-arglist-p)
  3839.         (cond
  3840.          ;; CASE 5B.1: a member init
  3841.          ((or (= char-before-ip ?:)
  3842.           (= char-after-ip ?:))
  3843.           ;; this line should be indented relative to the beginning
  3844.           ;; of indentation for the topmost-intro line that contains
  3845.           ;; the prototype's open paren
  3846.           ;; TBD: is the following redundant?
  3847.           (if (= char-before-ip ?:)
  3848.           (forward-char -1))
  3849.           (c-backward-syntactic-ws lim)
  3850.           ;; TBD: is the preceding redundant?
  3851.           (if (= (preceding-char) ?:)
  3852.           (progn (forward-char -1)
  3853.              (c-backward-syntactic-ws lim)))
  3854.           (if (= (preceding-char) ?\))
  3855.           (backward-sexp 1))
  3856.           (c-add-syntax 'member-init-intro (c-point 'boi))
  3857.           ;; we don't need to add any class offset since this
  3858.           ;; should be relative to the ctor's indentation
  3859.           )
  3860.          ;; CASE 5B.2: K&R arg decl intro
  3861.          (c-recognize-knr-p
  3862.           (c-add-syntax 'knr-argdecl-intro (c-point 'boi))
  3863.           (and inclass-p (c-add-syntax 'inclass (aref inclass-p 0))))
  3864.          ;; CASE 5B.3: Nether region after a C++ func decl, which
  3865.          ;; could include a `throw' declaration.
  3866.          (t
  3867.           (c-beginning-of-statement-1 lim)
  3868.           (c-add-syntax 'ansi-funcdecl-cont (c-point 'boi))
  3869.           )))
  3870.        ;; CASE 5C: inheritance line. could be first inheritance
  3871.        ;; line, or continuation of a multiple inheritance
  3872.        ((or (and c-baseclass-key (looking-at c-baseclass-key))
  3873.         (and (or (= char-before-ip ?:)
  3874.              (= char-after-ip ?:))
  3875.              (save-excursion
  3876.                (c-backward-syntactic-ws lim)
  3877.                (if (= char-before-ip ?:)
  3878.                (progn
  3879.                  (forward-char -1)
  3880.                  (c-backward-syntactic-ws lim)))
  3881.                (back-to-indentation)
  3882.                (looking-at c-class-key))))
  3883.         (cond
  3884.          ;; CASE 5C.1: non-hanging colon on an inher intro
  3885.          ((= char-after-ip ?:)
  3886.           (c-backward-syntactic-ws lim)
  3887.           (c-add-syntax 'inher-intro (c-point 'boi))
  3888.           ;; don't add inclass symbol since relative point already
  3889.           ;; contains any class offset
  3890.           )
  3891.          ;; CASE 5C.2: hanging colon on an inher intro
  3892.          ((= char-before-ip ?:)
  3893.           (c-add-syntax 'inher-intro (c-point 'boi))
  3894.           (and inclass-p (c-add-syntax 'inclass (aref inclass-p 0))))
  3895.          ;; CASE 5C.3: a continued inheritance line
  3896.          (t
  3897.           (c-beginning-of-inheritance-list lim)
  3898.           (c-add-syntax 'inher-cont (point))
  3899.           ;; don't add inclass symbol since relative point already
  3900.           ;; contains any class offset
  3901.           )))
  3902.        ;; CASE 5D: this could be a top-level compound statement or a
  3903.        ;; member init list continuation
  3904.        ((= char-before-ip ?,)
  3905.         (goto-char indent-point)
  3906.         (c-backward-syntactic-ws lim)
  3907.         (while (and (< lim (point))
  3908.             (= (preceding-char) ?,))
  3909.           ;; this will catch member inits with multiple
  3910.           ;; line arglists
  3911.           (forward-char -1)
  3912.           (c-backward-syntactic-ws (c-point 'bol))
  3913.           (if (= (preceding-char) ?\))
  3914.           (backward-sexp 1))
  3915.           ;; now continue checking
  3916.           (beginning-of-line)
  3917.           (c-backward-syntactic-ws lim))
  3918.         (cond
  3919.          ;; CASE 5D.1: hanging member init colon, but watch out
  3920.          ;; for bogus matches on access specifiers inside classes.
  3921.          ((and (= (preceding-char) ?:)
  3922.            (save-excursion
  3923.              (forward-word -1)
  3924.              (not (looking-at c-access-key))))
  3925.           (goto-char indent-point)
  3926.           (c-backward-syntactic-ws lim)
  3927.           (c-safe (backward-sexp 1))
  3928.           (c-add-syntax 'member-init-cont (c-point 'boi))
  3929.           ;; we do not need to add class offset since relative
  3930.           ;; point is the member init above us
  3931.           )
  3932.          ;; CASE 5D.2: non-hanging member init colon
  3933.          ((progn
  3934.         (c-forward-syntactic-ws indent-point)
  3935.         (= (following-char) ?:))
  3936.           (skip-chars-forward " \t:")
  3937.           (c-add-syntax 'member-init-cont (point)))
  3938.          ;; CASE 5D.3: perhaps a multiple inheritance line?
  3939.          ((looking-at c-inher-key)
  3940.           (c-add-syntax 'inher-cont (c-point 'boi)))
  3941.          ;; CASE 5D.4: perhaps a template list continuation?
  3942.          ((save-excursion
  3943.         (skip-chars-backward "^<" lim)
  3944.         ;; not sure if this is the right test, but it should
  3945.         ;; be fast and mostly accurate.
  3946.         (and (= (preceding-char) ?<)
  3947.              (not (c-in-literal lim))))
  3948.           ;; we can probably indent it just like and arglist-cont
  3949.           (c-add-syntax 'arglist-cont (point)))
  3950.          ;; CASE 5D.5: perhaps a top-level statement-cont
  3951.          (t
  3952.           (c-beginning-of-statement-1 lim)
  3953.           ;; skip over any access-specifiers
  3954.           (and inclass-p c-access-key
  3955.            (while (looking-at c-access-key)
  3956.              (forward-line 1)))
  3957.           ;; skip over comments, whitespace
  3958.           (c-forward-syntactic-ws indent-point)
  3959.           (c-add-syntax 'statement-cont (c-point 'boi)))
  3960.          ))
  3961.        ;; CASE 5E: we are looking at a access specifier
  3962.        ((and inclass-p
  3963.          c-access-key
  3964.          (looking-at c-access-key))
  3965.         (c-add-syntax 'access-label (c-point 'bonl))
  3966.         (c-add-syntax 'inclass (aref inclass-p 0)))
  3967.        ;; CASE 5F: we are looking at the brace which closes the
  3968.        ;; enclosing nested class decl
  3969.        ((and inclass-p
  3970.          (= char-after-ip ?})
  3971.          (save-excursion
  3972.            (save-restriction
  3973.              (widen)
  3974.              (forward-char 1)
  3975.              (and
  3976.               (condition-case nil
  3977.               (progn (backward-sexp 1) t)
  3978.             (error nil))
  3979.               (= (point) (aref inclass-p 1))
  3980.               ))))
  3981.         (save-restriction
  3982.           (widen)
  3983.           (goto-char (aref inclass-p 0))
  3984.           (c-add-syntax 'class-close (c-point 'boi))))
  3985.        ;; CASE 5G: we could be looking at subsequent knr-argdecls
  3986.        ((and c-recognize-knr-p
  3987.          (save-excursion
  3988.            (c-backward-syntactic-ws lim)
  3989.            (while (memq (preceding-char) '(?\; ?,))
  3990.              (beginning-of-line)
  3991.              (setq placeholder (point))
  3992.              (c-backward-syntactic-ws lim))
  3993.            (and (= (preceding-char) ?\))
  3994.             (or (not c-method-key)
  3995.                 (progn
  3996.                   (forward-sexp -1)
  3997.                   (forward-char -1)
  3998.                   (c-backward-syntactic-ws)
  3999.                   (not (or (= (preceding-char) ?-)
  4000.                        (= (preceding-char) ?+)
  4001.                        ;; or a class category
  4002.                        (progn
  4003.                      (forward-sexp -2)
  4004.                      (looking-at c-class-key))
  4005.                        )))))
  4006.            )
  4007.          (save-excursion
  4008.            (c-beginning-of-statement-1)
  4009.            (not (looking-at "typedef[ \t\n]+"))))
  4010.         (goto-char placeholder)
  4011.         (c-add-syntax 'knr-argdecl (c-point 'boi)))
  4012.        ;; CASE 5H: we are at the topmost level, make sure we skip
  4013.        ;; back past any access specifiers
  4014.        ((progn
  4015.           (c-backward-syntactic-ws lim)
  4016.           (while (and inclass-p
  4017.               c-access-key
  4018.               (not (bobp))
  4019.               (save-excursion
  4020.                 (c-safe (progn (backward-sexp 1) t))
  4021.                 (looking-at c-access-key)))
  4022.         (backward-sexp 1)
  4023.         (c-backward-syntactic-ws lim))
  4024.           (or (bobp)
  4025.           (memq (preceding-char) '(?\; ?\}))))
  4026.         ;; real beginning-of-line could be narrowed out due to
  4027.         ;; enclosure in a class block
  4028.         (save-restriction
  4029.           (widen)
  4030.           (c-add-syntax 'topmost-intro (c-point 'bol))
  4031.           (if inclass-p
  4032.           (progn
  4033.             (goto-char (aref inclass-p 1))
  4034.             (c-add-syntax 'inclass (c-point 'boi))))))
  4035.        ;; CASE 5I: we are at an ObjC or Java method definition
  4036.        ;; continuation line.
  4037.        ((and c-method-key
  4038.          (progn
  4039.            (c-beginning-of-statement-1 lim)
  4040.            (beginning-of-line)
  4041.            (looking-at c-method-key)))
  4042.         (c-add-syntax 'objc-method-args-cont (point)))
  4043.        ;; CASE 5J: we are at a topmost continuation line
  4044.        (t
  4045.         (c-beginning-of-statement-1 lim)
  4046.         (c-forward-syntactic-ws)
  4047.         (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
  4048.        ))                ; end CASE 5
  4049.      ;; CASE 6: line is an expression, not a statement.  Most
  4050.      ;; likely we are either in a function prototype or a function
  4051.      ;; call argument list
  4052.      ((/= (char-after containing-sexp) ?{)
  4053.       (c-backward-syntactic-ws containing-sexp)
  4054.       (cond
  4055.        ;; CASE 6A: we are looking at the arglist closing paren or
  4056.        ;; at an Objective-C or Java method call closing bracket.
  4057.        ((and (/= char-before-ip ?,)
  4058.          (memq char-after-ip '(?\) ?\])))
  4059.         (if (and c-method-key
  4060.              (progn
  4061.                (goto-char (1- containing-sexp))
  4062.                (c-backward-syntactic-ws lim)
  4063.                (not (looking-at c-symbol-key))))
  4064.         (c-add-syntax 'statement-cont containing-sexp)
  4065.           (goto-char containing-sexp)
  4066.           (c-add-syntax 'arglist-close (c-point 'boi))))
  4067.        ;; CASE 6B: we are looking at the first argument in an empty
  4068.        ;; argument list. Use arglist-close if we're actually
  4069.        ;; looking at a close paren or bracket.
  4070.        ((memq char-before-ip '(?\( ?\[))
  4071.         (goto-char containing-sexp)
  4072.         (c-add-syntax 'arglist-intro (c-point 'boi)))
  4073.        ;; CASE 6C: we are inside a conditional test clause. treat
  4074.        ;; these things as statements
  4075.        ((save-excursion
  4076.          (goto-char containing-sexp)
  4077.          (and (c-safe (progn (forward-sexp -1) t))
  4078.           (looking-at "\\<for\\>")))
  4079.         (goto-char (1+ containing-sexp))
  4080.         (c-forward-syntactic-ws indent-point)
  4081.         (c-beginning-of-statement-1 containing-sexp)
  4082.         (if (= char-before-ip ?\;)
  4083.         (c-add-syntax 'statement (point))
  4084.           (c-add-syntax 'statement-cont (point))
  4085.           ))
  4086.        ;; CASE 6D: maybe a continued method call. This is the case
  4087.        ;; when we are inside a [] bracketed exp, and what precede
  4088.        ;; the opening bracket is not an identifier.
  4089.        ((and c-method-key
  4090.          (= (char-after containing-sexp) ?\[)
  4091.          (save-excursion
  4092.            (goto-char (1- containing-sexp))
  4093.            (c-backward-syntactic-ws (c-point 'bod))
  4094.            (if (not (looking-at c-symbol-key))
  4095.                (c-add-syntax 'objc-method-call-cont containing-sexp))
  4096.            )))
  4097.        ;; CASE 6E: we are looking at an arglist continuation line,
  4098.        ;; but the preceding argument is on the same line as the
  4099.        ;; opening paren.  This case includes multi-line
  4100.        ;; mathematical paren groupings, but we could be on a
  4101.        ;; for-list continuation line
  4102.        ((and (save-excursion
  4103.            (goto-char (1+ containing-sexp))
  4104.            (skip-chars-forward " \t")
  4105.            (not (eolp)))
  4106.          (save-excursion
  4107.            (c-beginning-of-statement-1 lim)
  4108.            (skip-chars-backward " \t([")
  4109.            (<= (point) containing-sexp)))
  4110.         (goto-char containing-sexp)
  4111.         (c-add-syntax 'arglist-cont-nonempty (c-point 'boi)))
  4112.        ;; CASE 6F: we are looking at just a normal arglist
  4113.        ;; continuation line
  4114.        (t (c-beginning-of-statement-1 containing-sexp)
  4115.           (forward-char 1)
  4116.           (c-forward-syntactic-ws indent-point)
  4117.           (c-add-syntax 'arglist-cont (c-point 'boi)))
  4118.        ))
  4119.      ;; CASE 7: func-local multi-inheritance line
  4120.      ((and c-baseclass-key
  4121.            (save-excursion
  4122.          (goto-char indent-point)
  4123.          (skip-chars-forward " \t")
  4124.          (looking-at c-baseclass-key)))
  4125.       (goto-char indent-point)
  4126.       (skip-chars-forward " \t")
  4127.       (cond
  4128.        ;; CASE 7A: non-hanging colon on an inher intro
  4129.        ((= char-after-ip ?:)
  4130.         (c-backward-syntactic-ws lim)
  4131.         (c-add-syntax 'inher-intro (c-point 'boi)))
  4132.        ;; CASE 7B: hanging colon on an inher intro
  4133.        ((= char-before-ip ?:)
  4134.         (c-add-syntax 'inher-intro (c-point 'boi)))
  4135.        ;; CASE 7C: a continued inheritance line
  4136.        (t
  4137.         (c-beginning-of-inheritance-list lim)
  4138.         (c-add-syntax 'inher-cont (point))
  4139.         )))
  4140.      ;; CASE 8: we are inside a brace-list
  4141.      ((setq placeholder (c-inside-bracelist-p containing-sexp state))
  4142.       (cond
  4143.        ;; CASE 8A: brace-list-close brace
  4144.        ((and (= char-after-ip ?})
  4145.          (c-safe (progn (forward-char 1)
  4146.                 (backward-sexp 1)
  4147.                 t))
  4148.          (= (point) containing-sexp))
  4149.         (c-add-syntax 'brace-list-close (c-point 'boi)))
  4150.        ;; CASE 8B: we're looking at the first line in a brace-list
  4151.        ((save-excursion
  4152.           (goto-char indent-point)
  4153.           (c-backward-syntactic-ws containing-sexp)
  4154.           (= (point) (1+ containing-sexp)))
  4155.         (goto-char containing-sexp)
  4156.         ;;(if (= char-after-ip ?{)
  4157.         ;;(c-add-syntax 'brace-list-open (c-point 'boi))
  4158.         (c-add-syntax 'brace-list-intro (c-point 'boi))
  4159.         )
  4160.         ;;))            ; end CASE 8B
  4161.        ;; CASE 8C: this is just a later brace-list-entry
  4162.        (t (goto-char (1+ containing-sexp))
  4163.           (c-forward-syntactic-ws indent-point)
  4164.           (if (= char-after-ip ?{)
  4165.           (c-add-syntax 'brace-list-open (point))
  4166.         (c-add-syntax 'brace-list-entry (point))
  4167.         ))            ; end CASE 8C
  4168.        ))                ; end CASE 8
  4169.      ;; CASE 9: A continued statement
  4170.      ((and (not (memq char-before-ip '(?\; ?} ?:)))
  4171.            (> (point)
  4172.           (save-excursion
  4173.             (c-beginning-of-statement-1 containing-sexp)
  4174.             (setq placeholder (point))))
  4175.            (/= placeholder containing-sexp))
  4176.       (goto-char indent-point)
  4177.       (skip-chars-forward " \t")
  4178.       (let ((after-cond-placeholder
  4179.          (save-excursion
  4180.            (goto-char placeholder)
  4181.            (if (looking-at c-conditional-key)
  4182.                (progn
  4183.              (c-safe (c-skip-conditional))
  4184.              (c-forward-syntactic-ws)
  4185.              (if (memq (following-char) '(?\;))
  4186.                  (progn
  4187.                    (forward-char 1)
  4188.                    (c-forward-syntactic-ws)))
  4189.              (point))
  4190.              nil))))
  4191.         (cond
  4192.          ;; CASE 9A: substatement
  4193.          ((and after-cond-placeholder
  4194.            (>= after-cond-placeholder indent-point))
  4195.           (goto-char placeholder)
  4196.           (if (= char-after-ip ?{)
  4197.           (c-add-syntax 'substatement-open (c-point 'boi))
  4198.         (c-add-syntax 'substatement (c-point 'boi))))
  4199.          ;; CASE 9B: open braces for class or brace-lists
  4200.          ((= char-after-ip ?{)
  4201.           (cond
  4202.            ;; CASE 9B.1: class-open
  4203.            ((save-excursion
  4204.           (goto-char indent-point)
  4205.           (skip-chars-forward " \t{")
  4206.           (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
  4207.             (and decl
  4208.              (setq placeholder (aref decl 0)))
  4209.             ))
  4210.         (c-add-syntax 'class-open placeholder))
  4211.            ;; CASE 9B.2: brace-list-open
  4212.            ((or (save-excursion
  4213.               (goto-char placeholder)
  4214.               (looking-at "\\<enum\\>"))
  4215.             (= char-before-ip ?=))
  4216.         (c-add-syntax 'brace-list-open placeholder))
  4217.            ;; CASE 9B.3: catch-all for unknown construct.
  4218.            (t
  4219.         ;; Can and should I add an extensibility hook here?
  4220.         ;; Something like c-recognize-hook so support for
  4221.         ;; unknown constructs could be added.  It's probably a
  4222.         ;; losing proposition, so I dunno.
  4223.         (goto-char placeholder)
  4224.         (c-add-syntax 'statement-cont (c-point 'boi))
  4225.         (c-add-syntax 'block-open))
  4226.            ))
  4227.          ;; CASE 9C: iostream insertion or extraction operator
  4228.          ((looking-at "<<\\|>>")
  4229.           (goto-char placeholder)
  4230.           (and after-cond-placeholder
  4231.            (goto-char after-cond-placeholder))
  4232.           (while (and (re-search-forward "<<\\|>>" indent-point 'move)
  4233.               (c-in-literal placeholder)))
  4234.           ;; if we ended up at indent-point, then the first
  4235.           ;; streamop is on a separate line. Indent the line like
  4236.           ;; a statement-cont instead
  4237.           (if (/= (point) indent-point)
  4238.           (c-add-syntax 'stream-op (c-point 'boi))
  4239.         (c-backward-syntactic-ws lim)
  4240.         (c-add-syntax 'statement-cont (c-point 'boi))))
  4241.          ;; CASE 9D: continued statement. find the accurate
  4242.          ;; beginning of statement or substatement
  4243.          (t
  4244.           (c-beginning-of-statement-1 after-cond-placeholder)
  4245.           ;; KLUDGE ALERT!  c-beginning-of-statement-1 can leave
  4246.           ;; us before the lim we're passing in.  It should be
  4247.           ;; fixed, but I'm worried about side-effects at this
  4248.           ;; late date.  Fix for v5.
  4249.           (goto-char (or (and after-cond-placeholder
  4250.                   (max after-cond-placeholder (point)))
  4251.                  (point)))
  4252.           (c-add-syntax 'statement-cont (point)))
  4253.          )))
  4254.      ;; CASE 10: an else clause?
  4255.      ((looking-at "\\<else\\>[^_]")
  4256.       (c-backward-to-start-of-if containing-sexp)
  4257.       (c-add-syntax 'else-clause (c-point 'boi)))
  4258.      ;; CASE 11: Statement. But what kind?  Lets see if its a
  4259.      ;; while closure of a do/while construct
  4260.      ((progn
  4261.         (goto-char indent-point)
  4262.         (skip-chars-forward " \t")
  4263.         (and (looking-at "while\\b[^_]")
  4264.          (save-excursion
  4265.            (c-backward-to-start-of-do containing-sexp)
  4266.            (setq placeholder (point))
  4267.            (looking-at "do\\b[^_]"))
  4268.          ))
  4269.       (c-add-syntax 'do-while-closure placeholder))
  4270.      ;; CASE 12: A case or default label
  4271.      ((looking-at c-switch-label-key)
  4272.       (goto-char containing-sexp)
  4273.       ;; check for hanging braces
  4274.       (if (/= (point) (c-point 'boi))
  4275.           (forward-sexp -1))
  4276.       (c-add-syntax 'case-label (c-point 'boi)))
  4277.      ;; CASE 13: any other label
  4278.      ((looking-at c-label-key)
  4279.       (goto-char containing-sexp)
  4280.       (c-add-syntax 'label (c-point 'boi)))
  4281.      ;; CASE 14: block close brace, possibly closing the defun or
  4282.      ;; the class
  4283.      ((= char-after-ip ?})
  4284.       (let* ((lim (c-safe-position containing-sexp fullstate))
  4285.          (relpos (save-excursion
  4286.                (goto-char containing-sexp)
  4287.                (if (/= (point) (c-point 'boi))
  4288.                    (c-beginning-of-statement-1 lim))
  4289.                (c-point 'boi))))
  4290.         (cond
  4291.          ;; CASE 14A: does this close an inline?
  4292.          ((progn
  4293.         (goto-char containing-sexp)
  4294.         (c-search-uplist-for-classkey state))
  4295.           (c-add-syntax 'inline-close relpos))
  4296.          ;; CASE 14B: if there an enclosing brace that hasn't
  4297.          ;; been narrowed out by a class, then this is a
  4298.          ;; block-close
  4299.          ((c-most-enclosing-brace state)
  4300.           (c-add-syntax 'block-close relpos))
  4301.          ;; CASE 14C: find out whether we're closing a top-level
  4302.          ;; class or a defun
  4303.          (t
  4304.           (save-restriction
  4305.         (narrow-to-region (point-min) indent-point)
  4306.         (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
  4307.           (if decl
  4308.               (c-add-syntax 'class-close (aref decl 0))
  4309.             (c-add-syntax 'defun-close relpos)))))
  4310.          )))
  4311.      ;; CASE 15: statement catchall
  4312.      (t
  4313.       ;; we know its a statement, but we need to find out if it is
  4314.       ;; the first statement in a block
  4315.       (goto-char containing-sexp)
  4316.       (forward-char 1)
  4317.       (c-forward-syntactic-ws indent-point)
  4318.       ;; now skip forward past any case/default clauses we might find.
  4319.       (while (or (c-skip-case-statement-forward fullstate indent-point)
  4320.              (and (looking-at c-switch-label-key)
  4321.               (not inswitch-p)))
  4322.         (setq inswitch-p t))
  4323.       ;; we want to ignore non-case labels when skipping forward
  4324.       (while (and (looking-at c-label-key)
  4325.               (goto-char (match-end 0)))
  4326.         (c-forward-syntactic-ws indent-point))
  4327.       (cond
  4328.        ;; CASE 15A: we are inside a case/default clause inside a
  4329.        ;; switch statement.  find out if we are at the statement
  4330.        ;; just after the case/default label.
  4331.        ((and inswitch-p
  4332.          (progn
  4333.            (goto-char indent-point)
  4334.            (c-backward-syntactic-ws containing-sexp)
  4335.            (back-to-indentation)
  4336.            (setq placeholder (point))
  4337.            (looking-at c-switch-label-key)))
  4338.         (goto-char indent-point)
  4339.         (skip-chars-forward " \t")
  4340.         (if (= (following-char) ?{)
  4341.         (c-add-syntax 'statement-case-open placeholder)
  4342.           (c-add-syntax 'statement-case-intro placeholder)))
  4343.        ;; CASE 15B: continued statement
  4344.        ((= char-before-ip ?,)
  4345.         (c-add-syntax 'statement-cont (c-point 'boi)))
  4346.        ;; CASE 15C: a question/colon construct?  But make sure
  4347.        ;; what came before was not a label, and what comes after
  4348.        ;; is not a globally scoped function call!
  4349.        ((or (and (memq char-before-ip '(?: ??))
  4350.              (save-excursion
  4351.                (goto-char indent-point)
  4352.                (c-backward-syntactic-ws lim)
  4353.                (back-to-indentation)
  4354.                (not (looking-at c-label-key))))
  4355.         (and (memq char-after-ip '(?: ??))
  4356.              (save-excursion
  4357.                (goto-char indent-point)
  4358.                (skip-chars-forward " \t")
  4359.                ;; watch out for scope operator
  4360.                (not (looking-at "::")))))
  4361.         (c-add-syntax 'statement-cont (c-point 'boi)))
  4362.        ;; CASE 15D: any old statement
  4363.        ((< (point) indent-point)
  4364.         (let ((safepos (c-most-enclosing-brace fullstate)))
  4365.           (goto-char indent-point)
  4366.           (c-beginning-of-statement-1 safepos)
  4367.           ;; It is possible we're on the brace that opens a nested
  4368.           ;; function.
  4369.           (if (and (= (following-char) ?{)
  4370.                (save-excursion
  4371.              (c-backward-syntactic-ws safepos)
  4372.              (/= (preceding-char) ?\;)))
  4373.           (c-beginning-of-statement-1 safepos))
  4374.           (c-add-syntax 'statement (c-point 'boi))
  4375.           (if (= char-after-ip ?{)
  4376.           (c-add-syntax 'block-open))))
  4377.        ;; CASE 15E: first statement in an inline, or first
  4378.        ;; statement in a top-level defun. we can tell this is it
  4379.        ;; if there are no enclosing braces that haven't been
  4380.        ;; narrowed out by a class (i.e. don't use bod here!)
  4381.        ((save-excursion
  4382.           (save-restriction
  4383.         (widen)
  4384.         (goto-char containing-sexp)
  4385.         (c-narrow-out-enclosing-class state containing-sexp)
  4386.         (not (c-most-enclosing-brace state))))
  4387.         (goto-char containing-sexp)
  4388.         ;; if not at boi, then defun-opening braces are hung on
  4389.         ;; right side, so we need a different relpos
  4390.         (if (/= (point) (c-point 'boi))
  4391.         (progn
  4392.           (c-backward-syntactic-ws)
  4393.           (c-safe (forward-sexp (if (= (preceding-char) ?\))
  4394.                         -1 -2)))
  4395.           ))
  4396.         (c-add-syntax 'defun-block-intro (c-point 'boi)))
  4397.        ;; CASE 15F: first statement in a block
  4398.        (t (goto-char containing-sexp)
  4399.           (if (/= (point) (c-point 'boi))
  4400.           (c-beginning-of-statement-1
  4401.            (if (= (point) lim)
  4402.                (c-safe-position (point) state) lim)))
  4403.           (c-add-syntax 'statement-block-intro (c-point 'boi))
  4404.           (if (= char-after-ip ?{)
  4405.           (c-add-syntax 'block-open)))
  4406.        ))
  4407.      )
  4408.  
  4409.     ;; now we need to look at any modifiers
  4410.     (goto-char indent-point)
  4411.     (skip-chars-forward " \t")
  4412.     ;; are we looking at a comment only line?
  4413.     (if (looking-at c-comment-start-regexp)
  4414.         (c-add-syntax 'comment-intro))
  4415.     ;; we might want to give additional offset to friends (in C++).
  4416.     (if (and (eq major-mode 'c++-mode)
  4417.          (looking-at c-C++-friend-key))
  4418.         (c-add-syntax 'friend))
  4419.     ;; return the syntax
  4420.     syntax))))
  4421.  
  4422.  
  4423. ;; indent via syntactic language elements
  4424. (defun c-get-offset (langelem)
  4425.   ;; Get offset from LANGELEM which is a cons cell of the form:
  4426.   ;; (SYMBOL . RELPOS).  The symbol is matched against
  4427.   ;; c-offsets-alist and the offset found there is either returned,
  4428.   ;; or added to the indentation at RELPOS.  If RELPOS is nil, then
  4429.   ;; the offset is simply returned.
  4430.   (let* ((symbol (car langelem))
  4431.      (relpos (cdr langelem))
  4432.      (match  (assq symbol c-offsets-alist))
  4433.      (offset (cdr-safe match)))
  4434.     ;; offset can be a number, a function, a variable, or one of the
  4435.     ;; symbols + or -
  4436.     (cond
  4437.      ((not match)
  4438.       (if c-strict-syntax-p
  4439.       (error "don't know how to indent a %s" symbol)
  4440.     (setq offset 0
  4441.           relpos 0)))
  4442.      ((eq offset '+)  (setq offset c-basic-offset))
  4443.      ((eq offset '-)  (setq offset (- c-basic-offset)))
  4444.      ((eq offset '++) (setq offset (* 2 c-basic-offset)))
  4445.      ((eq offset '--) (setq offset (* 2 (- c-basic-offset))))
  4446.      ((eq offset '*)  (setq offset (/ c-basic-offset 2)))
  4447.      ((eq offset '/)  (setq offset (/ (- c-basic-offset) 2)))
  4448.      ((and (not (numberp offset))
  4449.        (fboundp offset))
  4450.       (setq offset (funcall offset langelem)))
  4451.      ((not (numberp offset))
  4452.       (setq offset (eval offset)))
  4453.      )
  4454.     (+ (if (and relpos
  4455.         (< relpos (c-point 'bol)))
  4456.        (save-excursion
  4457.          (goto-char relpos)
  4458.          (current-column))
  4459.      0)
  4460.        offset)))
  4461.  
  4462. (defun c-indent-line (&optional syntax)
  4463.   ;; indent the current line as C/C++/ObjC code. Optional SYNTAX is the
  4464.   ;; syntactic information for the current line. Returns the amount of
  4465.   ;; indentation change
  4466.   (let* ((c-syntactic-context (or syntax (c-guess-basic-syntax)))
  4467.      (pos (- (point-max) (point)))
  4468.      (indent (apply '+ (mapcar 'c-get-offset c-syntactic-context)))
  4469.      (shift-amt  (- (current-indentation) indent)))
  4470.     (and c-echo-syntactic-information-p
  4471.      (message "syntax: %s, indent= %d" c-syntactic-context indent))
  4472.     (if (zerop shift-amt)
  4473.     nil
  4474.       (delete-region (c-point 'bol) (c-point 'boi))
  4475.       (beginning-of-line)
  4476.       (indent-to indent))
  4477.     (if (< (point) (c-point 'boi))
  4478.     (back-to-indentation)
  4479.       ;; If initial point was within line's indentation, position after
  4480.       ;; the indentation.  Else stay at same point in text.
  4481.       (if (> (- (point-max) pos) (point))
  4482.       (goto-char (- (point-max) pos)))
  4483.       )
  4484.     (run-hooks 'c-special-indent-hook)
  4485.     shift-amt))
  4486.  
  4487. (defun c-show-syntactic-information ()
  4488.   "Show syntactic information for current line."
  4489.   (interactive)
  4490.   (message "syntactic analysis: %s" (c-guess-basic-syntax))
  4491.   (c-keep-region-active))
  4492.  
  4493.  
  4494. ;; Standard indentation line-ups
  4495. (defun c-lineup-arglist (langelem)
  4496.   ;; lineup the current arglist line with the arglist appearing just
  4497.   ;; after the containing paren which starts the arglist.
  4498.   (save-excursion
  4499.     (let* ((containing-sexp
  4500.         (save-excursion
  4501.           ;; arglist-cont-nonempty gives relpos ==
  4502.           ;; to boi of containing-sexp paren. This
  4503.           ;; is good when offset is +, but bad
  4504.           ;; when it is c-lineup-arglist, so we
  4505.           ;; have to special case a kludge here.
  4506.           (if (memq (car langelem) '(arglist-intro arglist-cont-nonempty))
  4507.           (progn
  4508.             (beginning-of-line)
  4509.             (backward-up-list 1)
  4510.             (skip-chars-forward " \t" (c-point 'eol)))
  4511.         (goto-char (cdr langelem)))
  4512.           (point)))
  4513.        (cs-curcol (save-excursion
  4514.             (goto-char (cdr langelem))
  4515.             (current-column))))
  4516.       (if (save-excursion
  4517.         (beginning-of-line)
  4518.         (looking-at "[ \t]*)"))
  4519.       (progn (goto-char (match-end 0))
  4520.          (forward-sexp -1)
  4521.          (forward-char 1)
  4522.          (c-forward-syntactic-ws)
  4523.          (- (current-column) cs-curcol))
  4524.     (goto-char containing-sexp)
  4525.     (or (eolp)
  4526.         (not (memq (following-char) '(?{ ?\( )))
  4527.         (let ((eol (c-point 'eol))
  4528.           (here (progn
  4529.               (forward-char 1)
  4530.               (skip-chars-forward " \t")
  4531.               (point))))
  4532.           (c-forward-syntactic-ws)
  4533.           (if (< (point) eol)
  4534.           (goto-char here))))
  4535.     (- (current-column) cs-curcol)
  4536.     ))))
  4537.  
  4538. (defun c-lineup-arglist-intro-after-paren (langelem)
  4539.   ;; lineup an arglist-intro line to just after the open paren
  4540.   (save-excursion
  4541.     (let ((cs-curcol (save-excursion
  4542.                (goto-char (cdr langelem))
  4543.                (current-column)))
  4544.       (ce-curcol (save-excursion
  4545.                (beginning-of-line)
  4546.                (backward-up-list 1)
  4547.                (skip-chars-forward " \t" (c-point 'eol))
  4548.                (current-column))))
  4549.       (- ce-curcol cs-curcol -1))))
  4550.  
  4551. (defun c-lineup-streamop (langelem)
  4552.   ;; lineup stream operators
  4553.   (save-excursion
  4554.     (let* ((relpos (cdr langelem))
  4555.        (curcol (progn (goto-char relpos)
  4556.               (current-column))))
  4557.       (re-search-forward "<<\\|>>" (c-point 'eol) 'move)
  4558.       (goto-char (match-beginning 0))
  4559.       (- (current-column) curcol))))
  4560.  
  4561. (defun c-lineup-multi-inher (langelem)
  4562.   ;; line up multiple inheritance lines
  4563.   (save-excursion
  4564.     (let (cs-curcol
  4565.       (eol (c-point 'eol))
  4566.       (here (point)))
  4567.       (goto-char (cdr langelem))
  4568.       (setq cs-curcol (current-column))
  4569.       (skip-chars-forward "^:" eol)
  4570.       (skip-chars-forward " \t:" eol)
  4571.       (if (or (eolp)
  4572.           (looking-at c-comment-start-regexp))
  4573.       (c-forward-syntactic-ws here))
  4574.       (- (current-column) cs-curcol)
  4575.       )))
  4576.  
  4577. (defun c-lineup-C-comments (langelem)
  4578.   ;; line up C block comment continuation lines
  4579.   (save-excursion
  4580.     (let ((stars (progn
  4581.            (beginning-of-line)
  4582.            (skip-chars-forward " \t")
  4583.            (if (looking-at "\\*\\*?")
  4584.                (- (match-end 0) (match-beginning 0))
  4585.              0)))
  4586.       (cs-curcol (progn (goto-char (cdr langelem))
  4587.                 (current-column))))
  4588.       (back-to-indentation)
  4589.       (if (re-search-forward "/\\*[ \t]*" (c-point 'eol) t)
  4590.       (goto-char (+ (match-beginning 0)
  4591.             (cond
  4592.              (c-block-comments-indent-p 0)
  4593.              ((= stars 1) 1)
  4594.              ((= stars 2) 0)
  4595.              (t (- (match-end 0) (match-beginning 0)))))))
  4596.       (- (current-column) cs-curcol))))
  4597.  
  4598. (defun c-lineup-comment (langelem)
  4599.   ;; support old behavior for comment indentation. we look at
  4600.   ;; c-comment-only-line-offset to decide how to indent comment
  4601.   ;; only-lines
  4602.   (save-excursion
  4603.     (back-to-indentation)
  4604.     ;; indent as specified by c-comment-only-line-offset
  4605.     (if (not (bolp))
  4606.     (or (car-safe c-comment-only-line-offset)
  4607.         c-comment-only-line-offset)
  4608.       (or (cdr-safe c-comment-only-line-offset)
  4609.       (car-safe c-comment-only-line-offset)
  4610.       -1000                ;jam it against the left side
  4611.       ))))
  4612.  
  4613. (defun c-lineup-runin-statements (langelem)
  4614.   ;; line up statements in coding standards which place the first
  4615.   ;; statement on the same line as the block opening brace.
  4616.   (if (= (char-after (cdr langelem)) ?{)
  4617.       (save-excursion
  4618.     (let ((curcol (progn
  4619.             (goto-char (cdr langelem))
  4620.             (current-column))))
  4621.       (forward-char 1)
  4622.       (skip-chars-forward " \t")
  4623.       (- (current-column) curcol)))
  4624.     0))
  4625.  
  4626. (defun c-lineup-math (langelem)
  4627.   ;; line up math statement-cont after the equals
  4628.   (save-excursion
  4629.     (let* ((relpos (cdr langelem))
  4630.        (equalp (save-excursion
  4631.              (goto-char (c-point 'boi))
  4632.              (skip-chars-forward "^=" (c-point 'eol))
  4633.              (and (= (following-char) ?=)
  4634.               (- (point) (c-point 'boi)))))
  4635.        (curcol (progn
  4636.              (goto-char relpos)
  4637.              (current-column)))
  4638.        donep)
  4639.       (while (and (not donep)
  4640.           (< (point) (c-point 'eol)))
  4641.     (skip-chars-forward "^=" (c-point 'eol))
  4642.     (if (c-in-literal (cdr langelem))
  4643.         (forward-char 1)
  4644.       (setq donep t)))
  4645.       (if (/= (following-char) ?=)
  4646.       ;; there's no equal sign on the line
  4647.       c-basic-offset
  4648.     ;; calculate indentation column after equals and ws, unless
  4649.     ;; our line contains an equals sign
  4650.     (if (not equalp)
  4651.         (progn
  4652.           (forward-char 1)
  4653.           (skip-chars-forward " \t")
  4654.           (setq equalp 0)))
  4655.     (- (current-column) equalp curcol))
  4656.       )))
  4657.  
  4658. (defun c-lineup-ObjC-method-call (langelem)
  4659.   ;; Line up methods args as elisp-mode does with function args: go to
  4660.   ;; the position right after the message receiver, and if you are at
  4661.   ;; (eolp) indent the current line by a constant offset from the
  4662.   ;; opening bracket; otherwise we are looking at the first character
  4663.   ;; of the first method call argument, so lineup the current line
  4664.   ;; with it.
  4665.   (save-excursion
  4666.     (let* ((extra (save-excursion
  4667.             (back-to-indentation)
  4668.             (c-backward-syntactic-ws (cdr langelem))
  4669.             (if (= (preceding-char) ?:)
  4670.             (- c-basic-offset)
  4671.               0)))
  4672.        (open-bracket-pos (cdr langelem))
  4673.            (open-bracket-col (progn
  4674.                    (goto-char open-bracket-pos)
  4675.                    (current-column)))
  4676.            (target-col (progn
  4677.              (forward-char)
  4678.              (forward-sexp)
  4679.              (skip-chars-forward " \t")
  4680.              (if (eolp)
  4681.                  (+ open-bracket-col c-basic-offset)
  4682.                (current-column))))
  4683.        )
  4684.       (- target-col open-bracket-col extra))))
  4685.  
  4686. (defun c-lineup-ObjC-method-args (langelem)
  4687.   ;; Line up the colons that separate args. This is done trying to
  4688.   ;; align colons vertically.
  4689.   (save-excursion
  4690.     (let* ((here (c-point 'boi))
  4691.        (curcol (progn (goto-char here) (current-column)))
  4692.        (eol (c-point 'eol))
  4693.        (relpos (cdr langelem))
  4694.        (first-col-column (progn
  4695.                    (goto-char relpos)
  4696.                    (skip-chars-forward "^:" eol)
  4697.                    (and (= (following-char) ?:)
  4698.                     (current-column)))))
  4699.       (if (not first-col-column)
  4700.       c-basic-offset
  4701.     (goto-char here)
  4702.     (skip-chars-forward "^:" eol)
  4703.     (if (= (following-char) ?:)
  4704.         (+ curcol (- first-col-column (current-column)))
  4705.       c-basic-offset)))))
  4706.  
  4707. (defun c-lineup-ObjC-method-args-2 (langelem)
  4708.   ;; Line up the colons that separate args. This is done trying to
  4709.   ;; align the colon on the current line with the previous one.
  4710.   (save-excursion
  4711.     (let* ((here (c-point 'boi))
  4712.        (curcol (progn (goto-char here) (current-column)))
  4713.        (eol (c-point 'eol))
  4714.        (relpos (cdr langelem))
  4715.        (prev-col-column (progn
  4716.                   (skip-chars-backward "^:" relpos)
  4717.                   (and (= (preceding-char) ?:)
  4718.                    (- (current-column) 1)))))
  4719.       (if (not prev-col-column)
  4720.       c-basic-offset
  4721.     (goto-char here)
  4722.     (skip-chars-forward "^:" eol)
  4723.     (if (= (following-char) ?:)
  4724.         (+ curcol (- prev-col-column (current-column)))
  4725.       c-basic-offset)))))
  4726.  
  4727. (defun c-snug-do-while (syntax pos)
  4728.   "Dynamically calculate brace hanginess for do-while statements.
  4729. Using this function, `while' clauses that end a `do-while' block will
  4730. remain on the same line as the brace that closes that block.
  4731.  
  4732. See `c-hanging-braces-alist' for how to utilize this function as an
  4733. ACTION associated with `block-close' syntax."
  4734.   (save-excursion
  4735.     (let (langelem)
  4736.       (if (and (eq syntax 'block-close)
  4737.            (setq langelem (assq 'block-close c-syntactic-context))
  4738.            (progn (goto-char (cdr langelem))
  4739.               (if (= (following-char) ?{)
  4740.               (c-safe (forward-sexp -1)))
  4741.               (looking-at "\\<do\\>[^_]")))
  4742.       '(before)
  4743.     '(before after)))))
  4744.  
  4745.  
  4746. ;;; This page handles insertion and removal of backslashes for C macros.
  4747.  
  4748. (defun c-backslash-region (from to delete-flag)
  4749.   "Insert, align, or delete end-of-line backslashes on the lines in the region.
  4750. With no argument, inserts backslashes and aligns existing backslashes.
  4751. With an argument, deletes the backslashes.
  4752.  
  4753. This function does not modify the last line of the region if the region ends 
  4754. right at the start of the following line; it does not modify blank lines
  4755. at the start of the region.  So you can put the region around an entire macro
  4756. definition and conveniently use this command."
  4757.   (interactive "r\nP")
  4758.   (save-excursion
  4759.     (goto-char from)
  4760.     (let ((column c-backslash-column)
  4761.           (endmark (make-marker)))
  4762.       (move-marker endmark to)
  4763.       ;; Compute the smallest column number past the ends of all the lines.
  4764.       (if (not delete-flag)
  4765.           (while (< (point) to)
  4766.             (end-of-line)
  4767.             (if (= (preceding-char) ?\\)
  4768.                 (progn (forward-char -1)
  4769.                        (skip-chars-backward " \t")))
  4770.             (setq column (max column (1+ (current-column))))
  4771.             (forward-line 1)))
  4772.       ;; Adjust upward to a tab column, if that doesn't push past the margin.
  4773.       (if (> (% column tab-width) 0)
  4774.           (let ((adjusted (* (/ (+ column tab-width -1) tab-width) tab-width)))
  4775.             (if (< adjusted (window-width))
  4776.                 (setq column adjusted))))
  4777.       ;; Don't modify blank lines at start of region.
  4778.       (goto-char from)
  4779.       (while (and (< (point) endmark) (eolp))
  4780.         (forward-line 1))
  4781.       ;; Add or remove backslashes on all the lines.
  4782.       (while (and (< (point) endmark)
  4783.                   ;; Don't backslashify the last line
  4784.                   ;; if the region ends right at the start of the next line.
  4785.                   (save-excursion
  4786.                     (forward-line 1)
  4787.                     (< (point) endmark)))
  4788.         (if (not delete-flag)
  4789.             (c-append-backslash column)
  4790.           (c-delete-backslash))
  4791.         (forward-line 1))
  4792.       (move-marker endmark nil))))
  4793.  
  4794. (defun c-append-backslash (column)
  4795.   (end-of-line)
  4796.   ;; Note that "\\\\" is needed to get one backslash.
  4797.   (if (= (preceding-char) ?\\)
  4798.       (progn (forward-char -1)
  4799.              (delete-horizontal-space)
  4800.              (indent-to column))
  4801.     (indent-to column)
  4802.     (insert "\\")))
  4803.  
  4804. (defun c-delete-backslash ()
  4805.   (end-of-line)
  4806.   (or (bolp)
  4807.       (progn
  4808.      (forward-char -1)
  4809.      (if (looking-at "\\\\")
  4810.          (delete-region (1+ (point))
  4811.                 (progn (skip-chars-backward " \t") (point)))))))
  4812.  
  4813.  
  4814. ;; defuns for submitting bug reports
  4815.  
  4816. (defconst c-version (concat "4.282"
  4817.                 " as included in "
  4818.                 emacs-version)
  4819.   "cc-mode version number.")
  4820. (defconst c-mode-help-address "bug-gnu-emacs@prep.ai.mit.edu"
  4821.   "Address for cc-mode bug reports.")
  4822.  
  4823. (defun c-version ()
  4824.   "Echo the current version of cc-mode in the minibuffer."
  4825.   (interactive)
  4826.   (message "Using cc-mode version %s" c-version)
  4827.   (c-keep-region-active))
  4828.  
  4829. ;; get reporter-submit-bug-report when byte-compiling
  4830. (eval-when-compile
  4831.   (require 'reporter))
  4832.  
  4833. (defun c-submit-bug-report ()
  4834.   "Submit via mail a bug report on cc-mode."
  4835.   (interactive)
  4836.   ;; load in reporter
  4837.   (let ((reporter-prompt-for-summary-p t)
  4838.     (reporter-dont-compact-list '(c-offsets-alist)))
  4839.     (and
  4840.      (if (y-or-n-p "Do you want to submit a report on cc-mode? ")
  4841.      t (message "") nil)
  4842.      (require 'reporter)
  4843.      (reporter-submit-bug-report
  4844.       c-mode-help-address
  4845.       (concat "cc-mode " c-version " ("
  4846.           (cond ((eq major-mode 'c++-mode)  "C++")
  4847.             ((eq major-mode 'c-mode)    "C")
  4848.             ((eq major-mode 'objc-mode) "ObjC")
  4849.             ((eq major-mode 'java-mode) "Java")
  4850.             )
  4851.           ")")
  4852.       (let ((vars (list
  4853.            ;; report only the vars that affect indentation
  4854.            'c-basic-offset
  4855.            'c-offsets-alist
  4856.            'c-block-comments-indent-p
  4857.            'c-cleanup-list
  4858.            'c-comment-only-line-offset
  4859.            'c-backslash-column
  4860.            'c-delete-function
  4861.            'c-electric-pound-behavior
  4862.            'c-hanging-braces-alist
  4863.            'c-hanging-colons-alist
  4864.            'c-hanging-comment-ender-p
  4865.            'c-tab-always-indent
  4866.            'c-recognize-knr-p
  4867.            'defun-prompt-regexp
  4868.            'tab-width
  4869.            )))
  4870.     (if (not (boundp 'defun-prompt-regexp))
  4871.         (delq 'defun-prompt-regexp vars)
  4872.       vars))
  4873.       (function
  4874.        (lambda ()
  4875.      (insert
  4876.       (if c-special-indent-hook
  4877.           (concat "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
  4878.               "c-special-indent-hook is set to '"
  4879.               (format "%s" c-special-indent-hook)
  4880.               ".\nPerhaps this is your problem?\n"
  4881.               "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n")
  4882.         "\n")
  4883.       (format "c-emacs-features: %s\n" c-emacs-features)
  4884.       )))
  4885.       nil
  4886.       "Dear Barry,"
  4887.       ))))
  4888.  
  4889.  
  4890. ;; menus for XEmacs 19
  4891. (defun c-popup-menu (e)
  4892.   "Pops up the C/C++/ObjC menu."
  4893.   (interactive "@e")
  4894.   (popup-menu (cons (concat mode-name " Mode Commands") c-mode-menu))
  4895.   (c-keep-region-active))
  4896.     
  4897.  
  4898. (defun c-copy-tree (tree)
  4899.   ;; Lift XEmacs 19.12's copy-tree
  4900.   (if (consp tree)
  4901.       (cons (c-copy-tree (car tree))
  4902.         (c-copy-tree (cdr tree)))
  4903.     (if (vectorp tree)
  4904.     (let* ((new (copy-sequence tree))
  4905.            (i (1- (length new))))
  4906.       (while (>= i 0)
  4907.         (aset new i (c-copy-tree (aref new i)))
  4908.         (setq i (1- i)))
  4909.       new)
  4910.       tree)))
  4911.  
  4912. (defun c-mapcar-defun (var)
  4913.   (let ((val (symbol-value var)))
  4914.     (cons var (if (atom val) val
  4915.         ;; XEmacs 19.12 and Emacs 19 + lucid.el have this
  4916.         (if (fboundp 'copy-tree)
  4917.             (copy-tree val)
  4918.           ;; Emacs 19 and Emacs 18
  4919.           (c-copy-tree val)
  4920.           )))
  4921.     ))
  4922.  
  4923. ;; Dynamically append the default value of most variables. This is
  4924. ;; crucial because future c-set-style calls will always reset the
  4925. ;; variables first to the `cc-mode' style before instituting the new
  4926. ;; style.  Only do this once!
  4927. (or (assoc "cc-mode" c-style-alist)
  4928.     (progn
  4929.       (c-add-style "cc-mode"
  4930.            (mapcar 'c-mapcar-defun
  4931.                '(c-backslash-column
  4932.                  c-basic-offset
  4933.                  c-block-comments-indent-p
  4934.                  c-cleanup-list
  4935.                  c-comment-only-line-offset
  4936.                  c-echo-syntactic-information-p
  4937.                  c-electric-pound-behavior
  4938.                  c-hanging-braces-alist
  4939.                  c-hanging-colons-alist
  4940.                  c-hanging-comment-ender-p
  4941.                  c-offsets-alist
  4942.                  c-recognize-knr-p
  4943.                  c-strict-syntax-p
  4944.                  c-tab-always-indent
  4945.                  c-inhibit-startup-warnings-p
  4946.                  )))
  4947.       ;; the default style is now GNU.  This can be overridden in
  4948.       ;; c-mode-common-hook or {c,c++,objc}-mode-hook.
  4949.       (c-set-style c-site-default-style)))
  4950.  
  4951. ;; style variables
  4952. (make-variable-buffer-local 'c-offsets-alist)
  4953. (make-variable-buffer-local 'c-basic-offset)
  4954. (make-variable-buffer-local 'c-file-style)
  4955. (make-variable-buffer-local 'c-file-offsets)
  4956. (make-variable-buffer-local 'c-comment-only-line-offset)
  4957. (make-variable-buffer-local 'c-block-comments-indent-p)
  4958. (make-variable-buffer-local 'c-cleanup-list)
  4959. (make-variable-buffer-local 'c-hanging-braces-alist)
  4960. (make-variable-buffer-local 'c-hanging-colons-alist)
  4961. (make-variable-buffer-local 'c-hanging-comment-ender-p)
  4962. (make-variable-buffer-local 'c-backslash-column)
  4963.  
  4964.  
  4965.  
  4966. ;; fsets for compatibility with BOCM
  4967. (fset 'electric-c-brace      'c-electric-brace)
  4968. (fset 'electric-c-semi       'c-electric-semi&comma)
  4969. (fset 'electric-c-sharp-sign 'c-electric-pound)
  4970. ;; there is no cc-mode equivalent for electric-c-terminator
  4971. (fset 'mark-c-function       'c-mark-function)
  4972. (fset 'indent-c-exp          'c-indent-exp)
  4973. ;;;###autoload (fset 'set-c-style           'c-set-style)
  4974. ;; Lucid Emacs 19.9 + font-lock + cc-mode - c++-mode lossage
  4975. (fset 'c++-beginning-of-defun 'beginning-of-defun)
  4976. (fset 'c++-end-of-defun 'end-of-defun)
  4977.  
  4978. ;; set up bc warnings for obsolete variables, but for now lets not
  4979. ;; worry about obsolete functions.  maybe later some will be important
  4980. ;; to flag
  4981. (and (memq 'v19 c-emacs-features)
  4982.      (let* ((na "Nothing appropriate.")
  4983.         (vars
  4984.          (list
  4985.           (cons 'c++-c-mode-syntax-table 'c-mode-syntax-table)
  4986.           (cons 'c++-tab-always-indent 'c-tab-always-indent)
  4987.           (cons 'c++-always-arglist-indent-p na)
  4988.           (cons 'c++-block-close-brace-offset 'c-offsets-alist)
  4989.           (cons 'c++-paren-as-block-close-p na)
  4990.           (cons 'c++-continued-member-init-offset 'c-offsets-alist)
  4991.           (cons 'c++-member-init-indent 'c-offsets-alist)
  4992.           (cons 'c++-friend-offset na)
  4993.           (cons 'c++-access-specifier-offset 'c-offsets-alist)
  4994.           (cons 'c++-empty-arglist-indent 'c-offsets-alist)
  4995.           (cons 'c++-comment-only-line-offset 'c-comment-only-line-offset)
  4996.           (cons 'c++-C-block-comments-indent-p 'c-block-comments-indent-p)
  4997.           (cons 'c++-cleanup-list 'c-cleanup-list)
  4998.           (cons 'c++-hanging-braces 'c-hanging-braces-alist)
  4999.           (cons 'c++-hanging-member-init-colon 'c-hanging-colons-alist)
  5000.           (cons 'c++-auto-hungry-initial-state
  5001.             "Use `c-auto-newline' and `c-hungry-delete-key' instead.")
  5002.           (cons 'c++-auto-hungry-toggle na)
  5003.           (cons 'c++-relative-offset-p na)
  5004.           (cons 'c++-special-indent-hook 'c-special-indent-hook)
  5005.           (cons 'c++-delete-function 'c-delete-function)
  5006.           (cons 'c++-electric-pound-behavior 'c-electric-pound-behavior)
  5007.           (cons 'c++-hungry-delete-key 'c-hungry-delete-key)
  5008.           (cons 'c++-auto-newline 'c-auto-newline)
  5009.           (cons 'c++-match-header-strongly na)
  5010.           (cons 'c++-defun-header-strong-struct-equivs na)
  5011.           (cons 'c++-version 'c-version)
  5012.           (cons 'c++-mode-help-address 'c-mode-help-address)
  5013.           (cons 'c-indent-level 'c-basic-offset)
  5014.           (cons 'c-brace-imaginary-offset na)
  5015.           (cons 'c-brace-offset 'c-offsets-alist)
  5016.           (cons 'c-argdecl-indent 'c-offsets-alist)
  5017.           (cons 'c-label-offset 'c-offsets-alist)
  5018.           (cons 'c-continued-statement-offset 'c-offsets-alist)
  5019.           (cons 'c-continued-brace-offset 'c-offsets-alist)
  5020.           (cons 'c-default-macroize-column 'c-backslash-column)
  5021.           (cons 'c++-default-macroize-column 'c-backslash-column)
  5022.           )))
  5023.        (mapcar
  5024.     (function
  5025.      (lambda (elt)
  5026.        (make-obsolete-variable (car elt) (cdr elt))))
  5027.     vars)))
  5028.  
  5029. (provide 'cc-mode)
  5030. ;;; cc-mode.el ends here
  5031.